first commit
This commit is contained in:
commit
faf2de70aa
677
LICENSE
Normal file
677
LICENSE
Normal file
@ -0,0 +1,677 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized international standards body, or, in
|
||||
the case of interfaces specified for a particular programming
|
||||
language, one that is widely used among developers working in that
|
||||
language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or modifying the covered
|
||||
works for you must do so exclusively on your behalf, under your
|
||||
direction and control, on terms that prohibit them from making any
|
||||
copies of your copyrighted material outside their relationship with
|
||||
you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where the
|
||||
Corresponding Source is located. Regardless of what server hosts
|
||||
the Corresponding Source, you remain obligated to ensure that it
|
||||
is available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal,
|
||||
family, or household purposes, or (2) anything designed or sold for
|
||||
incorporation into a dwelling. In determining whether a product is a
|
||||
consumer product, doubtful cases shall be resolved in favor of coverage.
|
||||
For a particular product received by a particular user, "normally used"
|
||||
refers to a typical or common use of that class of product, regardless
|
||||
of the status of the particular user or of the way in which the
|
||||
particular user actually uses, or expects or is expected to use, the
|
||||
product. A product is a consumer product regardless of whether the
|
||||
product has substantial commercial, industrial or non-consumer uses,
|
||||
unless such uses represent the only significant mode of use of the
|
||||
product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as if they were included in this License, to the extent that
|
||||
they are valid under applicable law. If additional permissions apply
|
||||
only to part of the Program, that part may be used separately under
|
||||
those permissions, but the entire Program remains governed by this
|
||||
License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a surcharge for exercising rights granted under this
|
||||
License, and you may not impose any (including a cross-claim or
|
||||
counterclaim in a lawsuit) alleging that any patent claim is
|
||||
infringed by making, using, selling, offering for sale, or importing
|
||||
the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to any recipient of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
47
README.md
Normal file
47
README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Pumpkin Plugin API for Python
|
||||
|
||||
This package provides everything needed to write a Pumpkin server plugin compiled to WebAssembly using Python.
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Install `pumpkin-api-py`:
|
||||
|
||||
```bash
|
||||
pip install pumpkin-api-py
|
||||
```
|
||||
|
||||
2. Create your plugin (`main.py`):
|
||||
|
||||
```python
|
||||
from pumpkin_api import (
|
||||
Plugin, PluginMetadata, register_plugin,
|
||||
server, event, command, text, context
|
||||
)
|
||||
|
||||
class MyPlugin(Plugin):
|
||||
def metadata(self) -> PluginMetadata:
|
||||
return PluginMetadata(
|
||||
name="my-plugin",
|
||||
version="0.1.0",
|
||||
authors=["you"],
|
||||
description="An example plugin."
|
||||
)
|
||||
|
||||
def on_load(self, ctx: context.Context) -> None:
|
||||
print("Python plugin loaded!")
|
||||
|
||||
# Register an event handler
|
||||
self.register_event(ctx, event.EventType.PLAYER_JOIN_EVENT, self.on_player_join)
|
||||
|
||||
def on_player_join(self, srv: server.Server, evt: event.PlayerJoinEventData) -> event.PlayerJoinEventData:
|
||||
print(f"Player {evt.player.get_name()} joined!")
|
||||
return evt
|
||||
|
||||
register_plugin(MyPlugin)
|
||||
```
|
||||
|
||||
3. Build your plugin into a WebAssembly component:
|
||||
|
||||
```bash
|
||||
pumpkin-api-build main -o my_plugin.wasm
|
||||
```
|
||||
36
example/main.py
Normal file
36
example/main.py
Normal file
@ -0,0 +1,36 @@
|
||||
from pumpkin_api import (
|
||||
Plugin, PluginMetadata, register_plugin,
|
||||
server, event, command, text, context
|
||||
)
|
||||
from pumpkin_api.app import WitWorld, Metadata
|
||||
|
||||
class MyPlugin(Plugin):
|
||||
def metadata(self) -> PluginMetadata:
|
||||
return PluginMetadata(
|
||||
name="my-plugin",
|
||||
version="0.1.0",
|
||||
authors=["you"],
|
||||
description="An example python plugin."
|
||||
)
|
||||
|
||||
def on_load(self, ctx: context.Context) -> None:
|
||||
print("Python plugin loaded!")
|
||||
|
||||
# Register an event handler
|
||||
self.register_event(ctx, event.EventType.PLAYER_JOIN_EVENT, self.on_player_join)
|
||||
|
||||
# Register a command
|
||||
# cmd = command.Command(["hello"], "A simple hello command")
|
||||
# self.register_command(ctx, cmd, self.hello_command)
|
||||
|
||||
def on_player_join(self, srv: server.Server, evt: event.PlayerJoinEventData) -> event.PlayerJoinEventData:
|
||||
print(f"Player {evt.player.get_name()} joined!")
|
||||
# We can modify the join message
|
||||
# evt.join_message = text.TextComponent_text("Welcome to the server!")
|
||||
return evt
|
||||
|
||||
def hello_command(self, sender: command.CommandSender, srv: server.Server, args: command.ConsumedArgs) -> int:
|
||||
sender.send_message(text.TextComponent_text("Hello from Python!"))
|
||||
return 1
|
||||
|
||||
register_plugin(MyPlugin)
|
||||
22
pyproject.toml
Normal file
22
pyproject.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[project]
|
||||
name = "pumpkin-api-py"
|
||||
version = "0.1.0.dev0"
|
||||
description = "Pumpkin plugin API for Python"
|
||||
authors = [{name = "alex"}]
|
||||
license = "GPL-3.0-only"
|
||||
dependencies = [
|
||||
"componentize-py>=0.22.1",
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
[project.scripts]
|
||||
pumpkin-api-build = "pumpkin_api.build:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/pumpkin_api"]
|
||||
include = ["src/pumpkin_api/wit_files/**/*.wit"]
|
||||
139
src/pumpkin_api/__init__.py
Normal file
139
src/pumpkin_api/__init__.py
Normal file
@ -0,0 +1,139 @@
|
||||
# pumpkin-api-py: Pumpkin plugin API for Python
|
||||
# Copyright (C) 2024 alex
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'wit'))
|
||||
|
||||
from typing import Dict, Callable, Any, Type, Optional, List, Union
|
||||
|
||||
from .wit.wit_world.imports import (
|
||||
server, event, command, context, text, scheduler,
|
||||
logging, gui, scoreboard, i18n, player, world,
|
||||
common, entity, permission
|
||||
)
|
||||
from .wit.wit_world.exports import metadata
|
||||
from componentize_py_types import Err
|
||||
|
||||
class PluginMetadata(metadata.PluginMetadata):
|
||||
pass
|
||||
|
||||
_PLUGIN_INSTANCE: Optional['Plugin'] = None
|
||||
_EVENT_HANDLERS: Dict[int, Callable[[server.Server, Any], Any]] = {}
|
||||
_COMMAND_HANDLERS: Dict[int, Callable[[command.CommandSender, server.Server, command.ConsumedArgs], int]] = {}
|
||||
_TASK_HANDLERS: Dict[int, Callable[[server.Server], None]] = {}
|
||||
_NEXT_HANDLER_ID: int = 0
|
||||
|
||||
def _get_next_handler_id() -> int:
|
||||
global _NEXT_HANDLER_ID
|
||||
handler_id = _NEXT_HANDLER_ID
|
||||
_NEXT_HANDLER_ID += 1
|
||||
return handler_id
|
||||
|
||||
class Plugin:
|
||||
def __init__(self):
|
||||
self._pending_events = []
|
||||
|
||||
def metadata(self) -> PluginMetadata:
|
||||
raise NotImplementedError
|
||||
|
||||
def on_load(self, ctx: context.Context) -> None:
|
||||
for event_type, handler, priority, blocking in self._pending_events:
|
||||
self.register_event(ctx, event_type, handler, priority, blocking)
|
||||
|
||||
def on_unload(self, ctx: context.Context) -> None:
|
||||
pass
|
||||
|
||||
def register_event(self, ctx: context.Context, event_type: event.EventType, handler: Callable[[server.Server, Any], Any], priority=event.EventPriority.NORMAL, blocking=True):
|
||||
handler_id = _get_next_handler_id()
|
||||
_EVENT_HANDLERS[handler_id] = handler
|
||||
ctx.register_event(handler_id, event_type, priority, blocking)
|
||||
|
||||
def register_command(self, ctx: context.Context, cmd: command.Command, handler: Callable[[command.CommandSender, server.Server, command.ConsumedArgs], int], permission: str = ""):
|
||||
handler_id = _get_next_handler_id()
|
||||
_COMMAND_HANDLERS[handler_id] = handler
|
||||
cmd.execute_with_handler_id(handler_id)
|
||||
ctx.register_command(cmd, permission)
|
||||
|
||||
def schedule_delayed_task(self, delay_ticks: int, handler: Callable[[server.Server], None]) -> int:
|
||||
handler_id = _get_next_handler_id()
|
||||
_TASK_HANDLERS[handler_id] = handler
|
||||
return scheduler.schedule_delayed_task(handler_id, delay_ticks)
|
||||
|
||||
def schedule_repeating_task(self, delay_ticks: int, period_ticks: int, handler: Callable[[server.Server], None]) -> int:
|
||||
handler_id = _get_next_handler_id()
|
||||
_TASK_HANDLERS[handler_id] = handler
|
||||
return scheduler.schedule_repeating_task(handler_id, delay_ticks, period_ticks)
|
||||
|
||||
def event_handler(self, event_type: event.EventType, priority=event.EventPriority.NORMAL, blocking=True):
|
||||
def decorator(func):
|
||||
self._pending_events.append((event_type, func, priority, blocking))
|
||||
return func
|
||||
return decorator
|
||||
|
||||
def register_plugin(plugin_class: Type[Plugin]):
|
||||
global _PLUGIN_INSTANCE
|
||||
_PLUGIN_INSTANCE = plugin_class()
|
||||
|
||||
class WitWorldImpl:
|
||||
def init_plugin(self) -> None:
|
||||
pass
|
||||
|
||||
def on_load(self, ctx: context.Context) -> None:
|
||||
if _PLUGIN_INSTANCE:
|
||||
try:
|
||||
# In WIT, on-load returns result<_, string>
|
||||
# componentize-py handles this by expecting None or raising Err
|
||||
_PLUGIN_INSTANCE.on_load(ctx)
|
||||
except Exception as e:
|
||||
raise Err(str(e))
|
||||
|
||||
def on_unload(self, ctx: context.Context) -> None:
|
||||
if _PLUGIN_INSTANCE:
|
||||
try:
|
||||
_PLUGIN_INSTANCE.on_unload(ctx)
|
||||
except Exception as e:
|
||||
raise Err(str(e))
|
||||
|
||||
def handle_event(self, event_id: int, srv: server.Server, evt: event.Event) -> event.Event:
|
||||
if event_id in _EVENT_HANDLERS:
|
||||
# Pass the inner event data to the handler
|
||||
result = _EVENT_HANDLERS[event_id](srv, evt.value)
|
||||
# If the handler returns something, assume it's the updated event data
|
||||
if result is not None:
|
||||
evt.value = result
|
||||
return evt
|
||||
|
||||
def handle_command(self, command_id: int, sender: command.CommandSender, srv: server.Server, args: command.ConsumedArgs) -> int:
|
||||
if command_id in _COMMAND_HANDLERS:
|
||||
try:
|
||||
return _COMMAND_HANDLERS[command_id](sender, srv, args)
|
||||
except Exception as e:
|
||||
if hasattr(e, 'value') and isinstance(e.value, (command.CommandError_InvalidConsumption, command.CommandError_InvalidRequirement, command.CommandError_PermissionDenied, command.CommandError_CommandFailed)):
|
||||
raise e
|
||||
raise Err(command.CommandError_CommandFailed(text.TextComponent_text(str(e))))
|
||||
|
||||
raise Err(command.CommandError_CommandFailed(text.TextComponent_text(f"no handler registered for command id {command_id}")))
|
||||
|
||||
def handle_task(self, handler_id: int, srv: server.Server) -> None:
|
||||
if handler_id in _TASK_HANDLERS:
|
||||
_TASK_HANDLERS[handler_id](srv)
|
||||
|
||||
class MetadataImpl:
|
||||
def get_metadata(self) -> metadata.PluginMetadata:
|
||||
if _PLUGIN_INSTANCE:
|
||||
return _PLUGIN_INSTANCE.metadata()
|
||||
return PluginMetadata("unknown", "0.0.0", [], "No metadata")
|
||||
8
src/pumpkin_api/app.py
Normal file
8
src/pumpkin_api/app.py
Normal file
@ -0,0 +1,8 @@
|
||||
from . import WitWorldImpl, MetadataImpl
|
||||
from .wit import wit_world
|
||||
|
||||
class WitWorld(WitWorldImpl, wit_world.WitWorld):
|
||||
pass
|
||||
|
||||
class Metadata(MetadataImpl, wit_world.exports.Metadata):
|
||||
pass
|
||||
35
src/pumpkin_api/build.py
Normal file
35
src/pumpkin_api/build.py
Normal file
@ -0,0 +1,35 @@
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Build a Pumpkin Python plugin")
|
||||
parser.add_argument("app_module", help="The python module containing the plugin (e.g. 'main')")
|
||||
parser.add_argument("-o", "--output", default="plugin.wasm", help="Output wasm file name")
|
||||
args = parser.parse_args()
|
||||
|
||||
import pumpkin_api
|
||||
pkg_dir = os.path.dirname(pumpkin_api.__file__)
|
||||
wit_dir = os.path.join(pkg_dir, "wit_files")
|
||||
|
||||
# Pass the parent directory of pumpkin_api to componentize-py so it can resolve `pumpkin_api` module
|
||||
# in case it's not installed in a standard site-packages (e.g. editable install or no venv)
|
||||
pkg_parent_dir = os.path.dirname(pkg_dir)
|
||||
|
||||
cmd = [
|
||||
"componentize-py",
|
||||
"-d", wit_dir,
|
||||
"-w", "plugin",
|
||||
"componentize", args.app_module,
|
||||
"-o", args.output,
|
||||
"-p", ".",
|
||||
"-p", pkg_parent_dir
|
||||
]
|
||||
|
||||
print(f"Running: {' '.join(cmd)}")
|
||||
result = subprocess.run(cmd)
|
||||
sys.exit(result.returncode)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
529
src/pumpkin_api/wit/componentize_py_async_support/__init__.py
Normal file
529
src/pumpkin_api/wit/componentize_py_async_support/__init__.py
Normal file
@ -0,0 +1,529 @@
|
||||
import asyncio
|
||||
import componentize_py_runtime
|
||||
import subprocess
|
||||
|
||||
from os import PathLike
|
||||
from socket import AddressFamily, AddressInfo, SocketKind, socket
|
||||
from concurrent.futures import Executor
|
||||
from componentize_py_types import Result, Ok, Err
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional, TypeVar, TypeVarTuple, Callable, IO, Literal, cast
|
||||
from contextvars import ContextVar, Context
|
||||
from collections.abc import Coroutine, Awaitable, Sequence
|
||||
from asyncio.protocols import BaseProtocol
|
||||
from asyncio.transports import Transport, WriteTransport, DatagramTransport, SubprocessTransport, ReadTransport
|
||||
from asyncio.base_events import Server
|
||||
|
||||
try:
|
||||
from ssl import SSLContext
|
||||
except:
|
||||
pass
|
||||
|
||||
@dataclass
|
||||
class _FutureState:
|
||||
waitable_set: int | None
|
||||
futures: dict[int, Any]
|
||||
handles: list[asyncio.Handle]
|
||||
pending_count: int
|
||||
|
||||
class _ReturnCode:
|
||||
COMPLETED = 0
|
||||
DROPPED = 1
|
||||
CANCELLED = 2
|
||||
|
||||
class _CallbackCode:
|
||||
EXIT = 0
|
||||
YIELD = 1
|
||||
WAIT = 2
|
||||
POLL = 3
|
||||
|
||||
class _Event:
|
||||
NONE = 0
|
||||
SUBTASK = 1
|
||||
STREAM_READ = 2
|
||||
STREAM_WRITE = 3
|
||||
FUTURE_READ = 4
|
||||
FUTURE_WRITE = 5
|
||||
CANCELLED = 6
|
||||
|
||||
class _Status:
|
||||
STARTING = 0
|
||||
STARTED = 1
|
||||
RETURNED = 2
|
||||
START_CANCELLED = 3
|
||||
RETURN_CANCELLED = 4
|
||||
|
||||
_T = TypeVar("_T")
|
||||
_Ts = TypeVarTuple("_Ts")
|
||||
_ProtocolT = TypeVar("_ProtocolT", bound=BaseProtocol)
|
||||
|
||||
async def _noop() -> None:
|
||||
pass
|
||||
|
||||
class _Loop(asyncio.AbstractEventLoop):
|
||||
def __init__(self) -> None:
|
||||
self.running: bool = False
|
||||
self.exception: Optional[Any] = None
|
||||
|
||||
def poll(self, future_state: _FutureState) -> None:
|
||||
while True:
|
||||
handles = future_state.handles
|
||||
future_state.handles = []
|
||||
for handle in handles:
|
||||
if not handle._cancelled:
|
||||
handle._run()
|
||||
|
||||
if self.exception is not None:
|
||||
raise self.exception
|
||||
|
||||
if len(handles) == 0 and len(future_state.handles) == 0:
|
||||
return
|
||||
|
||||
def get_debug(self) -> bool:
|
||||
return False
|
||||
|
||||
def is_running(self) -> bool:
|
||||
return self.running
|
||||
|
||||
def is_closed(self) -> bool:
|
||||
return not self.running
|
||||
|
||||
def stop(self) -> None:
|
||||
self.running = False
|
||||
|
||||
def close(self) -> None:
|
||||
self.running = False
|
||||
|
||||
def shutdown_asyncgens(self) -> Coroutine[Any, Any, None]:
|
||||
return _noop()
|
||||
|
||||
def call_exception_handler(self, context: dict[str, Any]) -> None:
|
||||
self.exception = context.get('exception', None)
|
||||
|
||||
def call_soon(self,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.Handle:
|
||||
global _future_state
|
||||
|
||||
if context is not None:
|
||||
future_state = context[_future_state]
|
||||
handle = asyncio.Handle(callback, args, self, context)
|
||||
future_state.handles.append(handle)
|
||||
return handle
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def create_task(self, coroutine: Coroutine[Any, Any, _T], name: str | None = None, context: Context | None = None) -> asyncio.Task[_T]:
|
||||
return asyncio.Task(coroutine, loop=self, context=context)
|
||||
|
||||
def create_future(self) -> asyncio.Future[Any]:
|
||||
return asyncio.Future(loop=self)
|
||||
|
||||
# The remaining methods should be irrelevant for our purposes and thus unimplemented
|
||||
|
||||
def run_until_complete(self, future: Awaitable[_T]) -> _T:
|
||||
raise NotImplementedError
|
||||
|
||||
def run_forever(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def shutdown_default_executor(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def call_later(self,
|
||||
delay: float,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.TimerHandle:
|
||||
raise NotImplementedError
|
||||
|
||||
def call_at(self,
|
||||
when: float,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.TimerHandle:
|
||||
raise NotImplementedError
|
||||
|
||||
def time(self) -> float:
|
||||
raise NotImplementedError
|
||||
|
||||
def call_soon_threadsafe(self,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.Handle:
|
||||
raise NotImplementedError
|
||||
|
||||
def run_in_executor(self,
|
||||
executor: Executor | None,
|
||||
func: Callable[[*_Ts], _T],
|
||||
*args: *_Ts) -> asyncio.Future[_T]:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_default_executor(self, executor: Executor) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def getaddrinfo(
|
||||
self,
|
||||
host: bytes | str | None,
|
||||
port: bytes | str | int | None,
|
||||
*,
|
||||
family: int = 0,
|
||||
type: int = 0,
|
||||
proto: int = 0,
|
||||
flags: int = 0,
|
||||
) -> list[tuple[AddressFamily, SocketKind, int, str, tuple[str, int] | tuple[str, int, int, int]]]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def getnameinfo(self,
|
||||
sockaddr: tuple[str, int] | tuple[str, int, int, int],
|
||||
flags: int = 0) -> tuple[str, str]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_connection(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
host: str | None = ...,
|
||||
port: int | None = ...,
|
||||
*,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
family: int = 0,
|
||||
proto: int = 0,
|
||||
flags: int = 0,
|
||||
sock: socket | None = None,
|
||||
local_addr: tuple[str, int] | None = None,
|
||||
server_hostname: str | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
happy_eyeballs_delay: float | None = None,
|
||||
interleave: int | None = None,
|
||||
) -> tuple[Transport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_server(
|
||||
self,
|
||||
protocol_factory: Callable[[], BaseProtocol],
|
||||
host: str | Sequence[str] | None = None,
|
||||
port: int | None = None,
|
||||
*,
|
||||
family: int = AddressFamily.AF_UNSPEC,
|
||||
flags: int = AddressInfo.AI_PASSIVE,
|
||||
sock: socket | None = ...,
|
||||
backlog: int = 100,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
reuse_address: bool | None = None,
|
||||
reuse_port: bool | None = None,
|
||||
keep_alive: bool | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
start_serving: bool = True,
|
||||
) -> Server:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sendfile(self,
|
||||
transport: WriteTransport,
|
||||
file: IO[bytes],
|
||||
offset: int = 0,
|
||||
count: int | None = None,
|
||||
*,
|
||||
fallback: bool = True
|
||||
) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
async def start_tls(
|
||||
self,
|
||||
transport: WriteTransport,
|
||||
protocol: BaseProtocol,
|
||||
sslcontext: SSLContext,
|
||||
*,
|
||||
server_side: bool = False,
|
||||
server_hostname: str | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
) -> Transport | None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_connection(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
path: str | None = None,
|
||||
*,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
sock: socket | None = None,
|
||||
server_hostname: str | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
) -> tuple[Transport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_server(
|
||||
self,
|
||||
protocol_factory: Callable[[], BaseProtocol],
|
||||
path: str | PathLike[str] | None = None,
|
||||
*,
|
||||
sock: socket | None = None,
|
||||
backlog: int = 100,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
start_serving: bool = True,
|
||||
) -> Server:
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_accepted_socket(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
sock: socket,
|
||||
*,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
) -> tuple[Transport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_datagram_endpoint(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
local_addr: tuple[str, int] | str | None = None,
|
||||
remote_addr: tuple[str, int] | str | None = None,
|
||||
*,
|
||||
family: int = 0,
|
||||
proto: int = 0,
|
||||
flags: int = 0,
|
||||
reuse_address: bool | None = None,
|
||||
reuse_port: bool | None = None,
|
||||
allow_broadcast: bool | None = None,
|
||||
sock: socket | None = None,
|
||||
) -> tuple[DatagramTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_read_pipe(self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
pipe: Any) -> tuple[ReadTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_write_pipe(self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
pipe: Any) -> tuple[WriteTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_shell(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
cmd: bytes | str,
|
||||
*,
|
||||
stdin: int | IO[Any] | None = -1,
|
||||
stdout: int | IO[Any] | None = -1,
|
||||
stderr: int | IO[Any] | None = -1,
|
||||
universal_newlines: Literal[False] = False,
|
||||
shell: Literal[True] = True,
|
||||
bufsize: Literal[0] = 0,
|
||||
encoding: None = None,
|
||||
errors: None = None,
|
||||
text: Literal[False] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> tuple[SubprocessTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_exec(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
program: Any,
|
||||
*args: Any,
|
||||
stdin: int | IO[Any] | None = -1,
|
||||
stdout: int | IO[Any] | None = -1,
|
||||
stderr: int | IO[Any] | None = -1,
|
||||
universal_newlines: Literal[False] = False,
|
||||
shell: Literal[False] = False,
|
||||
bufsize: Literal[0] = 0,
|
||||
encoding: None = None,
|
||||
errors: None = None,
|
||||
**kwargs: Any,
|
||||
) -> tuple[SubprocessTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
def add_reader(self, fd: Any, callback: Callable[[*_Ts], Any], *args: *_Ts) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_reader(self, fd: Any) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def add_writer(self, fd: Any, callback: Callable[[*_Ts], Any], *args: *_Ts) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_writer(self, fd: Any) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv(self, sock: socket, nbytes: int) -> bytes:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv_into(self, sock: socket, buf: Any) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom(self, sock: socket, bufsize: int) -> tuple[bytes, Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom_into(self, sock: socket, buf: Any, nbytes: int = 0) -> tuple[int, Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendall(self, sock: socket, data: Any) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendto(self, sock: socket, data: Any, address: Any) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_connect(self, sock: socket, address: Any) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_accept(self, sock: socket) -> tuple[socket, Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendfile(
|
||||
self,
|
||||
sock: socket,
|
||||
file: IO[bytes],
|
||||
offset: int = 0,
|
||||
count: int | None = None,
|
||||
*,
|
||||
fallback: bool | None = None
|
||||
) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
def add_signal_handler(self, sig: int, callback: Callable[[*_Ts], object], *args: *_Ts) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_signal_handler(self, sig: int) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_task_factory(self, factory: Any | None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_task_factory(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_exception_handler(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_exception_handler(self, handler: Any | None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def default_exception_handler(self, context: dict[str, Any]) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_debug(self, enabled: bool) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
_future_state: ContextVar[_FutureState] = ContextVar("_future_state")
|
||||
_loop = _Loop()
|
||||
asyncio.set_event_loop(_loop)
|
||||
_loop.running = True
|
||||
asyncio.events._set_running_loop(_loop)
|
||||
|
||||
def _set_future_state(future_state: _FutureState) -> None:
|
||||
global _future_state
|
||||
|
||||
_future_state.set(future_state)
|
||||
|
||||
async def _return_result(export_index: int, borrows: int, coroutine: Any) -> None:
|
||||
global _future_state
|
||||
|
||||
try:
|
||||
try:
|
||||
result: Result[Any, Any] = Ok(await coroutine)
|
||||
except Err as e:
|
||||
result = e
|
||||
|
||||
componentize_py_runtime.call_task_return(export_index, borrows, result)
|
||||
except Exception as e:
|
||||
_loop.exception = e
|
||||
|
||||
assert _future_state.get().pending_count > 0
|
||||
_future_state.get().pending_count -= 1
|
||||
|
||||
def first_poll(export_index: int, borrows: int, coroutine: Any) -> int:
|
||||
context = Context()
|
||||
future_state = _FutureState(None, {}, [], 1)
|
||||
context.run(_set_future_state, future_state)
|
||||
asyncio.create_task(_return_result(export_index, borrows, coroutine), context=context)
|
||||
return _poll(future_state)
|
||||
|
||||
def _poll(future_state: _FutureState) -> int:
|
||||
global _loop
|
||||
|
||||
_loop.poll(future_state)
|
||||
|
||||
if future_state.pending_count == 0:
|
||||
if future_state.waitable_set is not None:
|
||||
componentize_py_runtime.waitable_set_drop(future_state.waitable_set)
|
||||
|
||||
return _CallbackCode.EXIT
|
||||
else:
|
||||
waitable_set = future_state.waitable_set
|
||||
assert waitable_set is not None
|
||||
componentize_py_runtime.context_set(future_state)
|
||||
return _CallbackCode.WAIT | (waitable_set << 4)
|
||||
|
||||
def callback(event0: int, event1: int, event2: int) -> int:
|
||||
future_state = componentize_py_runtime.context_get()
|
||||
componentize_py_runtime.context_set(None)
|
||||
|
||||
match event0:
|
||||
case _Event.NONE:
|
||||
pass
|
||||
case _Event.SUBTASK:
|
||||
match event2:
|
||||
case _Status.STARTING:
|
||||
raise AssertionError
|
||||
case _Status.STARTED:
|
||||
pass
|
||||
case _Status.RETURNED:
|
||||
componentize_py_runtime.waitable_join(event1, 0)
|
||||
componentize_py_runtime.subtask_drop(event1)
|
||||
future_state.futures.pop(event1).set_result(event2)
|
||||
case _:
|
||||
# todo
|
||||
raise NotImplementedError
|
||||
case _Event.STREAM_READ | _Event.STREAM_WRITE | _Event.FUTURE_READ | _Event.FUTURE_WRITE:
|
||||
componentize_py_runtime.waitable_join(event1, 0)
|
||||
future_state.futures.pop(event1).set_result(event2)
|
||||
case _:
|
||||
# todo
|
||||
raise NotImplementedError
|
||||
|
||||
return _poll(future_state)
|
||||
|
||||
async def await_result[T](result: Result[T, tuple[int, int]]) -> T:
|
||||
global _loop
|
||||
global _future_state
|
||||
|
||||
if isinstance(result, Ok):
|
||||
return result.value
|
||||
else:
|
||||
future_state = _future_state.get()
|
||||
waitable, promise = result.value
|
||||
future = _loop.create_future()
|
||||
future_state.futures[waitable] = future
|
||||
|
||||
if future_state.waitable_set is None:
|
||||
future_state.waitable_set = componentize_py_runtime.waitable_set_new()
|
||||
componentize_py_runtime.waitable_join(waitable, future_state.waitable_set)
|
||||
|
||||
return cast(T, componentize_py_runtime.promise_get_result(await future, promise))
|
||||
|
||||
async def _wrap_spawned(coroutine: Any) -> None:
|
||||
global _future_state
|
||||
|
||||
try:
|
||||
await coroutine
|
||||
except Exception as e:
|
||||
_loop.exception = e
|
||||
|
||||
assert _future_state.get().pending_count > 0
|
||||
_future_state.get().pending_count -= 1
|
||||
|
||||
def spawn(coroutine: Any) -> None:
|
||||
global _future_state
|
||||
|
||||
_future_state.get().pending_count += 1
|
||||
|
||||
asyncio.create_task(_wrap_spawned(coroutine))
|
||||
93
src/pumpkin_api/wit/componentize_py_async_support/futures.py
Normal file
93
src/pumpkin_api/wit/componentize_py_async_support/futures.py
Normal file
@ -0,0 +1,93 @@
|
||||
import componentize_py_runtime
|
||||
import componentize_py_async_support
|
||||
import weakref
|
||||
|
||||
from typing import TypeVar, Generic, cast, Self, Any, Callable
|
||||
from types import TracebackType
|
||||
from componentize_py_async_support import _ReturnCode
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class FutureReader(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.future_drop_readable, type_, handle)
|
||||
|
||||
async def read(self) -> T:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
result = await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.future_read(self.type_, handle)
|
||||
)
|
||||
componentize_py_runtime.future_drop_readable(self.type_, handle)
|
||||
return cast(T, result)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
if self.handle is not None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
componentize_py_runtime.future_drop_readable(self.type_, handle)
|
||||
|
||||
return None
|
||||
|
||||
async def write(type_: int, handle: int, value: Any) -> None:
|
||||
await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.future_write(type_, handle, value)
|
||||
)
|
||||
componentize_py_runtime.future_drop_writable(type_, handle)
|
||||
|
||||
def write_default(type_: int, handle: int, default: Callable[[], Any]) -> None:
|
||||
componentize_py_async_support.spawn(write(type_, handle, default()))
|
||||
|
||||
class FutureWriter(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int, default: Callable[[], T]):
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.default = default
|
||||
self.finalizer = weakref.finalize(self, write_default, type_, handle, default)
|
||||
|
||||
async def write(self, value: T) -> bool:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
code, _ = await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.future_write(self.type_, handle, value)
|
||||
)
|
||||
componentize_py_runtime.future_drop_writable(self.type_, handle)
|
||||
match code:
|
||||
case _ReturnCode.COMPLETED:
|
||||
return True
|
||||
case _ReturnCode.DROPPED:
|
||||
return False
|
||||
case _ReturnCode.CANCELLED:
|
||||
# todo
|
||||
raise NotImplementedError
|
||||
case _:
|
||||
raise AssertionError
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
if self.handle is not None:
|
||||
componentize_py_async_support.spawn(self.write(self.default()))
|
||||
|
||||
return None
|
||||
189
src/pumpkin_api/wit/componentize_py_async_support/streams.py
Normal file
189
src/pumpkin_api/wit/componentize_py_async_support/streams.py
Normal file
@ -0,0 +1,189 @@
|
||||
import componentize_py_runtime
|
||||
import componentize_py_async_support
|
||||
import weakref
|
||||
|
||||
from typing import TypeVar, Generic, Self, cast
|
||||
from types import TracebackType
|
||||
from componentize_py_async_support import _ReturnCode
|
||||
|
||||
class ByteStreamReader:
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.writer_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_readable, type_, handle)
|
||||
|
||||
async def read(self, max_count: int) -> bytes:
|
||||
if self.writer_dropped:
|
||||
return bytes()
|
||||
|
||||
code, values = await self._read(max_count)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.writer_dropped = True
|
||||
|
||||
return values
|
||||
|
||||
async def _read(self, max_count: int) -> tuple[int, bytes]:
|
||||
if self.handle is not None:
|
||||
return cast(tuple[int, bytes], await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_read(self.type_, self.handle, max_count)
|
||||
))
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_readable(self.type_, handle)
|
||||
return None
|
||||
|
||||
class ByteStreamWriter:
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.reader_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_writable, type_, handle)
|
||||
|
||||
async def write(self, source: bytes) -> int:
|
||||
if self.reader_dropped:
|
||||
return 0
|
||||
|
||||
code, count = await self._write(source)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.reader_dropped = True
|
||||
|
||||
return count
|
||||
|
||||
async def _write(self, source: bytes) -> tuple[int, int]:
|
||||
if self.handle is not None:
|
||||
return await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_write(self.type_, self.handle, source)
|
||||
)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
async def write_all(self, source: bytes) -> int:
|
||||
total = 0
|
||||
|
||||
while len(source) > 0 and not self.reader_dropped:
|
||||
count = await self.write(source)
|
||||
source = source[count:]
|
||||
total += count
|
||||
|
||||
return total
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_writable(self.type_, handle)
|
||||
return None
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class StreamReader(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.writer_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_readable, type_, handle)
|
||||
|
||||
async def read(self, max_count: int) -> list[T]:
|
||||
if self.writer_dropped:
|
||||
return []
|
||||
|
||||
code, values = await self._read(max_count)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.writer_dropped = True
|
||||
|
||||
return values
|
||||
|
||||
async def _read(self, max_count: int) -> tuple[int, list[T]]:
|
||||
if self.handle is not None:
|
||||
return cast(tuple[int, list[T]], await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_read(self.type_, self.handle, max_count)
|
||||
))
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_readable(self.type_, handle)
|
||||
return None
|
||||
|
||||
class StreamWriter(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.reader_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_writable, type_, handle)
|
||||
|
||||
async def write(self, source: list[T]) -> int:
|
||||
if self.reader_dropped:
|
||||
return 0
|
||||
|
||||
code, count = await self._write(source)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.reader_dropped = True
|
||||
|
||||
return count
|
||||
|
||||
async def _write(self, source: list[T]) -> tuple[int, int]:
|
||||
if self.handle is not None:
|
||||
return await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_write(self.type_, self.handle, source)
|
||||
)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
async def write_all(self, source: list[T]) -> int:
|
||||
total = 0
|
||||
|
||||
while len(source) > 0 and not self.reader_dropped:
|
||||
count = await self.write(source)
|
||||
source = source[count:]
|
||||
total += count
|
||||
|
||||
return total
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_writable(self.type_, handle)
|
||||
return None
|
||||
34
src/pumpkin_api/wit/componentize_py_runtime.pyi
Normal file
34
src/pumpkin_api/wit/componentize_py_runtime.pyi
Normal file
@ -0,0 +1,34 @@
|
||||
from typing import Any
|
||||
from componentize_py_types import Result
|
||||
|
||||
def call_task_return(index: int, borrows: int, result: Any) -> None: ...
|
||||
|
||||
def waitable_set_drop(set: int) -> None: ...
|
||||
|
||||
def context_set(value: Any) -> None: ...
|
||||
|
||||
def context_get() -> Any: ...
|
||||
|
||||
def waitable_join(waitable: int, set: int) -> None: ...
|
||||
|
||||
def subtask_drop(task: int) -> None: ...
|
||||
|
||||
def waitable_set_new() -> int: ...
|
||||
|
||||
def promise_get_result(event: int, promise: int) -> Any: ...
|
||||
|
||||
def future_read(ty: int, future: int) -> Result[Any, tuple[int, int]]: ...
|
||||
|
||||
def future_write(ty: int, future: int, value: Any) -> Result[tuple[int, int], tuple[int, int]]: ...
|
||||
|
||||
def future_drop_readable(ty: int, future: int) -> None: ...
|
||||
|
||||
def future_drop_writable(ty: int, future: int) -> None: ...
|
||||
|
||||
def stream_read(ty: int, stream: int, max_count: int) -> Result[tuple[int, bytes | list[Any]], tuple[int, int]]: ...
|
||||
|
||||
def stream_write(ty: int, stream: int, values: bytes | list[Any]) -> Result[tuple[int, int], tuple[int, int]]: ...
|
||||
|
||||
def stream_drop_readable(ty: int, stream: int) -> None: ...
|
||||
|
||||
def stream_drop_writable(ty: int, stream: int) -> None: ...
|
||||
19
src/pumpkin_api/wit/componentize_py_types.py
Normal file
19
src/pumpkin_api/wit/componentize_py_types.py
Normal file
@ -0,0 +1,19 @@
|
||||
from typing import TypeVar, Generic, Union
|
||||
from dataclasses import dataclass
|
||||
|
||||
S = TypeVar('S')
|
||||
@dataclass
|
||||
class Some(Generic[S]):
|
||||
value: S
|
||||
|
||||
T = TypeVar('T')
|
||||
@dataclass
|
||||
class Ok(Generic[T]):
|
||||
value: T
|
||||
|
||||
E = TypeVar('E')
|
||||
@dataclass(frozen=True)
|
||||
class Err(Generic[E], Exception):
|
||||
value: E
|
||||
|
||||
Result = Union[Ok[T], Err[E]]
|
||||
440
src/pumpkin_api/wit/poll_loop.py
Normal file
440
src/pumpkin_api/wit/poll_loop.py
Normal file
@ -0,0 +1,440 @@
|
||||
"""Defines a custom `asyncio` event loop backed by `wasi:io/poll#poll`.
|
||||
|
||||
This also includes helper classes and functions for working with `wasi:http`.
|
||||
|
||||
This is only useful for `wasi:http@0.2.x`; `wasi:http@0.3.x` uses a different
|
||||
mechanism to model concurrency.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import socket
|
||||
import subprocess
|
||||
|
||||
from componentize_py_types import Ok, Err
|
||||
from wit_world.imports import types, streams, poll, outgoing_handler
|
||||
from wit_world.imports.types import (
|
||||
IncomingBody,
|
||||
OutgoingBody,
|
||||
OutgoingRequest,
|
||||
IncomingResponse,
|
||||
)
|
||||
from wit_world.imports.streams import StreamError_Closed, InputStream
|
||||
from wit_world.imports.poll import Pollable
|
||||
from typing import Optional, cast
|
||||
|
||||
# Maximum number of bytes to read at a time
|
||||
READ_SIZE: int = 16 * 1024
|
||||
|
||||
|
||||
async def send(request: OutgoingRequest) -> IncomingResponse:
|
||||
"""Send the specified request and wait asynchronously for the response."""
|
||||
|
||||
future = outgoing_handler.handle(request, None)
|
||||
|
||||
while True:
|
||||
response = future.get()
|
||||
if response is None:
|
||||
await register(cast(PollLoop, asyncio.get_event_loop()), future.subscribe())
|
||||
else:
|
||||
if isinstance(response, Ok):
|
||||
if isinstance(response.value, Ok):
|
||||
return response.value.value
|
||||
else:
|
||||
raise response.value
|
||||
else:
|
||||
raise response
|
||||
|
||||
|
||||
class Stream:
|
||||
"""Reader abstraction over `wasi:http/types#incoming-body`."""
|
||||
|
||||
def __init__(self, body: IncomingBody):
|
||||
self.body: Optional[IncomingBody] = body
|
||||
self.stream: Optional[InputStream] = body.stream()
|
||||
|
||||
async def next(self) -> Optional[bytes]:
|
||||
"""Wait for the next chunk of data to arrive on the stream.
|
||||
|
||||
This will return `None` when the end of the stream has been reached.
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
if self.stream is None:
|
||||
return None
|
||||
else:
|
||||
buffer = self.stream.read(READ_SIZE)
|
||||
if len(buffer) == 0:
|
||||
await register(
|
||||
cast(PollLoop, asyncio.get_event_loop()),
|
||||
self.stream.subscribe(),
|
||||
)
|
||||
else:
|
||||
return buffer
|
||||
except Err as e:
|
||||
if isinstance(e.value, StreamError_Closed):
|
||||
if self.stream is not None:
|
||||
self.stream.__exit__(None, None, None)
|
||||
self.stream = None
|
||||
if self.body is not None:
|
||||
IncomingBody.finish(self.body)
|
||||
self.body = None
|
||||
else:
|
||||
raise e
|
||||
|
||||
|
||||
class Sink:
|
||||
"""Writer abstraction over `wasi:http/types#outgoing-body`."""
|
||||
|
||||
def __init__(self, body: OutgoingBody):
|
||||
self.body = body
|
||||
self.stream = body.write()
|
||||
|
||||
async def send(self, chunk: bytes):
|
||||
"""Write the specified bytes to the sink.
|
||||
|
||||
This may need to yield according to the backpressure requirements of the sink.
|
||||
"""
|
||||
offset = 0
|
||||
flushing = False
|
||||
while True:
|
||||
count = self.stream.check_write()
|
||||
if count == 0:
|
||||
await register(
|
||||
cast(PollLoop, asyncio.get_event_loop()), self.stream.subscribe()
|
||||
)
|
||||
elif offset == len(chunk):
|
||||
if flushing:
|
||||
return
|
||||
else:
|
||||
self.stream.flush()
|
||||
flushing = True
|
||||
else:
|
||||
count = min(count, len(chunk) - offset)
|
||||
self.stream.write(chunk[offset : offset + count])
|
||||
offset += count
|
||||
|
||||
def close(self):
|
||||
"""Close the stream, indicating no further data will be written."""
|
||||
|
||||
self.stream.__exit__(None, None, None)
|
||||
self.stream = None
|
||||
OutgoingBody.finish(self.body, None)
|
||||
self.body = None
|
||||
|
||||
|
||||
class PollLoop(asyncio.AbstractEventLoop):
|
||||
"""Custom `asyncio` event loop backed by `wasi:io/poll#poll`."""
|
||||
|
||||
def __init__(self):
|
||||
self.wakers = []
|
||||
self.running = False
|
||||
self.handles = []
|
||||
self.exception = None
|
||||
|
||||
def get_debug(self):
|
||||
return False
|
||||
|
||||
def run_until_complete(self, future):
|
||||
future = asyncio.ensure_future(future, loop=self)
|
||||
|
||||
self.running = True
|
||||
asyncio.events._set_running_loop(self)
|
||||
while self.running and not future.done():
|
||||
handles = self.handles
|
||||
self.handles = []
|
||||
for handle in handles:
|
||||
if not handle._cancelled:
|
||||
handle._run()
|
||||
|
||||
if self.wakers:
|
||||
[pollables, wakers] = list(map(list, zip(*self.wakers)))
|
||||
|
||||
new_wakers = []
|
||||
ready = [False] * len(pollables)
|
||||
for index in poll.poll(pollables):
|
||||
ready[index] = True
|
||||
|
||||
for (ready, pollable), waker in zip(zip(ready, pollables), wakers):
|
||||
if ready:
|
||||
pollable.__exit__(None, None, None)
|
||||
waker.set_result(None)
|
||||
else:
|
||||
new_wakers.append((pollable, waker))
|
||||
|
||||
self.wakers = new_wakers
|
||||
|
||||
if self.exception is not None:
|
||||
raise self.exception
|
||||
|
||||
return future.result()
|
||||
|
||||
def is_running(self):
|
||||
return self.running
|
||||
|
||||
def is_closed(self):
|
||||
return not self.running
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
def close(self):
|
||||
self.running = False
|
||||
|
||||
def shutdown_asyncgens(self):
|
||||
pass
|
||||
|
||||
def call_exception_handler(self, context):
|
||||
self.exception = context.get("exception", None)
|
||||
|
||||
def call_soon(self, callback, *args, context=None):
|
||||
handle = asyncio.Handle(callback, args, self, context)
|
||||
self.handles.append(handle)
|
||||
return handle
|
||||
|
||||
def create_task(self, coroutine):
|
||||
return asyncio.Task(coroutine, loop=self)
|
||||
|
||||
def create_future(self):
|
||||
return asyncio.Future(loop=self)
|
||||
|
||||
# The remaining methods should be irrelevant for our purposes and thus unimplemented
|
||||
|
||||
def run_forever(self):
|
||||
raise NotImplementedError
|
||||
|
||||
async def shutdown_default_executor(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def _timer_handle_cancelled(self, handle):
|
||||
raise NotImplementedError
|
||||
|
||||
def call_later(self, delay, callback, *args, context=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def call_at(self, when, callback, *args, context=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def time(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def call_soon_threadsafe(self, callback, *args, context=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def run_in_executor(self, executor, func, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_default_executor(self, executor):
|
||||
raise NotImplementedError
|
||||
|
||||
async def getaddrinfo(self, host, port, *, family=0, type=0, proto=0, flags=0):
|
||||
raise NotImplementedError
|
||||
|
||||
async def getnameinfo(self, sockaddr, flags=0):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_connection(
|
||||
self,
|
||||
protocol_factory,
|
||||
host=None,
|
||||
port=None,
|
||||
*,
|
||||
ssl=None,
|
||||
family=0,
|
||||
proto=0,
|
||||
flags=0,
|
||||
sock=None,
|
||||
local_addr=None,
|
||||
server_hostname=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
happy_eyeballs_delay=None,
|
||||
interleave=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_server(
|
||||
self,
|
||||
protocol_factory,
|
||||
host=None,
|
||||
port=None,
|
||||
*,
|
||||
family=socket.AF_UNSPEC,
|
||||
flags=socket.AI_PASSIVE,
|
||||
sock=None,
|
||||
backlog=100,
|
||||
ssl=None,
|
||||
reuse_address=None,
|
||||
reuse_port=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
start_serving=True,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sendfile(self, transport, file, offset=0, count=None, *, fallback=True):
|
||||
raise NotImplementedError
|
||||
|
||||
async def start_tls(
|
||||
self,
|
||||
transport,
|
||||
protocol,
|
||||
sslcontext,
|
||||
*,
|
||||
server_side=False,
|
||||
server_hostname=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_connection(
|
||||
self,
|
||||
protocol_factory,
|
||||
path=None,
|
||||
*,
|
||||
ssl=None,
|
||||
sock=None,
|
||||
server_hostname=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_server(
|
||||
self,
|
||||
protocol_factory,
|
||||
path=None,
|
||||
*,
|
||||
sock=None,
|
||||
backlog=100,
|
||||
ssl=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
start_serving=True,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_accepted_socket(
|
||||
self,
|
||||
protocol_factory,
|
||||
sock,
|
||||
*,
|
||||
ssl=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_datagram_endpoint(
|
||||
self,
|
||||
protocol_factory,
|
||||
local_addr=None,
|
||||
remote_addr=None,
|
||||
*,
|
||||
family=0,
|
||||
proto=0,
|
||||
flags=0,
|
||||
reuse_address=None,
|
||||
reuse_port=None,
|
||||
allow_broadcast=None,
|
||||
sock=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_read_pipe(self, protocol_factory, pipe):
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_write_pipe(self, protocol_factory, pipe):
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_shell(
|
||||
self,
|
||||
protocol_factory,
|
||||
cmd,
|
||||
*,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
**kwargs,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_exec(
|
||||
self,
|
||||
protocol_factory,
|
||||
*args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
**kwargs,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_reader(self, fd, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_reader(self, fd):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_writer(self, fd, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_writer(self, fd):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv(self, sock, nbytes):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv_into(self, sock, buf):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom(self, sock, bufsize):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom_into(self, sock, buf, nbytes=0):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendall(self, sock, data):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendto(self, sock, data, address):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_connect(self, sock, address):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_accept(self, sock):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendfile(self, sock, file, offset=0, count=None, *, fallback=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_signal_handler(self, sig, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_signal_handler(self, sig):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_task_factory(self, factory):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_task_factory(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_exception_handler(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_exception_handler(self, handler):
|
||||
raise NotImplementedError
|
||||
|
||||
def default_exception_handler(self, context):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_debug(self, enabled):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
async def register(loop: PollLoop, pollable: Pollable):
|
||||
waker = loop.create_future()
|
||||
loop.wakers.append((pollable, waker))
|
||||
await waker
|
||||
70
src/pumpkin_api/wit/wit_world/__init__.py
Normal file
70
src/pumpkin_api/wit/wit_world/__init__.py
Normal file
@ -0,0 +1,70 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from .imports import event
|
||||
from .imports import server
|
||||
from .imports import command
|
||||
from .imports import context
|
||||
|
||||
|
||||
class WitWorld(Protocol):
|
||||
|
||||
@abstractmethod
|
||||
def init_plugin(self) -> None:
|
||||
"""
|
||||
--- Plugin-provided exports ---
|
||||
Called by the host once to initialize the plugin.
|
||||
Internal use only; plugins should use the `register_plugin!` macro.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def on_load(self, context: context.Context) -> None:
|
||||
"""
|
||||
Called when the plugin is being loaded.
|
||||
Use this to register commands, events, and perform initial setup.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.str)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def on_unload(self, context: context.Context) -> None:
|
||||
"""
|
||||
Called when the plugin is being unloaded.
|
||||
Use this to save data and clean up resources.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.str)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def handle_event(self, event_id: int, server: server.Server, event: event.Event) -> event.Event:
|
||||
"""
|
||||
Dispatches an event to the plugin for handling.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def handle_command(self, command_id: int, sender: command.CommandSender, server: server.Server, args: command.ConsumedArgs) -> int:
|
||||
"""
|
||||
Dispatches a command execution to the plugin.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.command.CommandError)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def handle_task(self, handler_id: int, server: server.Server) -> None:
|
||||
"""
|
||||
Dispatches a scheduled task execution to the plugin.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
19
src/pumpkin_api/wit/wit_world/exports/__init__.py
Normal file
19
src/pumpkin_api/wit/wit_world/exports/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..exports import metadata
|
||||
|
||||
class Metadata(Protocol):
|
||||
|
||||
@abstractmethod
|
||||
def get_metadata(self) -> metadata.PluginMetadata:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
22
src/pumpkin_api/wit/wit_world/exports/metadata.py
Normal file
22
src/pumpkin_api/wit/wit_world/exports/metadata.py
Normal file
@ -0,0 +1,22 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Plugin metadata describing the plugin and its compatibility.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
@dataclass
|
||||
class PluginMetadata:
|
||||
name: str
|
||||
version: str
|
||||
authors: List[str]
|
||||
description: str
|
||||
|
||||
0
src/pumpkin_api/wit/wit_world/imports/__init__.py
Normal file
0
src/pumpkin_api/wit/wit_world/imports/__init__.py
Normal file
539
src/pumpkin_api/wit/wit_world/imports/command.py
Normal file
539
src/pumpkin_api/wit/wit_world/imports/command.py
Normal file
@ -0,0 +1,539 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import entity
|
||||
from ..imports import text
|
||||
from ..imports import world
|
||||
from ..imports import player
|
||||
from ..imports import server
|
||||
|
||||
class Gamemode(Enum):
|
||||
SURVIVAL = 0
|
||||
CREATIVE = 1
|
||||
ADVENTURE = 2
|
||||
SPECTATOR = 3
|
||||
|
||||
class BossbarColor(Enum):
|
||||
PINK = 0
|
||||
BLUE = 1
|
||||
RED = 2
|
||||
GREEN = 3
|
||||
YELLOW = 4
|
||||
PURPLE = 5
|
||||
WHITE = 6
|
||||
|
||||
class BossbarStyle(Enum):
|
||||
NO_DIVISION = 0
|
||||
NOTCHES6 = 1
|
||||
NOTCHES10 = 2
|
||||
NOTCHES12 = 3
|
||||
NOTCHES20 = 4
|
||||
|
||||
class SoundCategory(Enum):
|
||||
MASTER = 0
|
||||
MUSIC = 1
|
||||
RECORDS = 2
|
||||
WEATHER = 3
|
||||
BLOCKS = 4
|
||||
HOSTILE = 5
|
||||
NEUTRAL = 6
|
||||
PLAYERS = 7
|
||||
AMBIENT = 8
|
||||
VOICE = 9
|
||||
UI = 10
|
||||
|
||||
class EntityAnchor(Enum):
|
||||
FEET = 0
|
||||
EYES = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Float64:
|
||||
value: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Float32:
|
||||
value: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Int32:
|
||||
value: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Int64:
|
||||
value: int
|
||||
|
||||
|
||||
Number = Union[Number_Float64, Number_Float32, Number_Int32, Number_Int64]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class NotInBounds_LowerBound:
|
||||
value: Tuple[Number, Number]
|
||||
|
||||
|
||||
@dataclass
|
||||
class NotInBounds_UpperBound:
|
||||
value: Tuple[Number, Number]
|
||||
|
||||
|
||||
NotInBounds = Union[NotInBounds_LowerBound, NotInBounds_UpperBound]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Entities:
|
||||
value: List[entity.Entity]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Entity:
|
||||
value: entity.Entity
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Players:
|
||||
value: List[player.Player]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BlockPos:
|
||||
value: Tuple[int, int, int]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Pos3d:
|
||||
value: Tuple[float, float, float]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Pos2d:
|
||||
value: Tuple[float, float]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Rotation:
|
||||
value: Tuple[float, bool, float, bool]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_GameMode:
|
||||
value: Gamemode
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Difficulty:
|
||||
value: server.Difficulty
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Item:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_ItemPredicate:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_ResourceLocation:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Block:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BlockPredicate:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BossbarColor:
|
||||
value: BossbarColor
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BossbarStyle:
|
||||
value: BossbarStyle
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Particle:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Msg:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_TextComponent:
|
||||
value: text.TextComponent
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Time:
|
||||
value: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Num:
|
||||
value: Result[Number, NotInBounds]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Bool:
|
||||
value: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Simple:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_SoundCategory:
|
||||
value: SoundCategory
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_DamageType:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Effect:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Enchantment:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_EntityAnchor:
|
||||
value: EntityAnchor
|
||||
|
||||
|
||||
Arg = Union[Arg_Entities, Arg_Entity, Arg_Players, Arg_BlockPos, Arg_Pos3d, Arg_Pos2d, Arg_Rotation, Arg_GameMode, Arg_Difficulty, Arg_Item, Arg_ItemPredicate, Arg_ResourceLocation, Arg_Block, Arg_BlockPredicate, Arg_BossbarColor, Arg_BossbarStyle, Arg_Particle, Arg_Msg, Arg_TextComponent, Arg_Time, Arg_Num, Arg_Bool, Arg_Simple, Arg_SoundCategory, Arg_DamageType, Arg_Effect, Arg_Enchantment, Arg_EntityAnchor]
|
||||
|
||||
|
||||
class ConsumedArgs:
|
||||
|
||||
def get_value(self, key: str) -> Arg:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Rcon:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Console:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Player:
|
||||
value: player.Player
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_CommandBlock:
|
||||
value: Tuple[entity.CommandBlockEntity, world.World]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Dummy:
|
||||
pass
|
||||
|
||||
|
||||
CommandSenderType = Union[CommandSenderType_Rcon, CommandSenderType_Console, CommandSenderType_Player, CommandSenderType_CommandBlock, CommandSenderType_Dummy]
|
||||
|
||||
|
||||
class PermissionLevel(Enum):
|
||||
ZERO = 0
|
||||
ONE = 1
|
||||
TWO = 2
|
||||
THREE = 3
|
||||
FOUR = 4
|
||||
|
||||
class CommandSender:
|
||||
|
||||
def get_command_sender_type(self) -> CommandSenderType:
|
||||
raise NotImplementedError
|
||||
def send_message(self, text: text.TextComponent) -> None:
|
||||
raise NotImplementedError
|
||||
def set_success_count(self, count: int) -> None:
|
||||
raise NotImplementedError
|
||||
def is_player(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def is_console(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def as_player(self) -> Optional[player.Player]:
|
||||
raise NotImplementedError
|
||||
def permission_level(self) -> PermissionLevel:
|
||||
raise NotImplementedError
|
||||
def has_permission_level(self, level: PermissionLevel) -> bool:
|
||||
raise NotImplementedError
|
||||
def has_permission(self, server: server.Server, node: str) -> bool:
|
||||
raise NotImplementedError
|
||||
def position(self) -> Optional[Tuple[float, float, float]]:
|
||||
raise NotImplementedError
|
||||
def world(self) -> Optional[world.World]:
|
||||
raise NotImplementedError
|
||||
def get_locale(self) -> common.Locale:
|
||||
raise NotImplementedError
|
||||
def should_receive_feedback(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def should_broadcast_console_to_ops(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def should_track_output(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class StringType(Enum):
|
||||
SINGLE_WORD = 0
|
||||
QUOTABLE = 1
|
||||
GREEDY = 2
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Bool:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Float:
|
||||
value: Tuple[Optional[float], Optional[float]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Double:
|
||||
value: Tuple[Optional[float], Optional[float]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Integer:
|
||||
value: Tuple[Optional[int], Optional[int]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Long:
|
||||
value: Tuple[Optional[int], Optional[int]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_String:
|
||||
value: StringType
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Entities:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Entity:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Players:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_GameProfile:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_BlockPos:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Position3d:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Position2d:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_BlockState:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_BlockPredicate:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Item:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_ItemPredicate:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Component:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Rotation:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_ResourceLocation:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_EntityAnchor:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Gamemode:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Difficulty:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Time:
|
||||
value: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Resource:
|
||||
value: str
|
||||
|
||||
|
||||
ArgumentType = Union[ArgumentType_Bool, ArgumentType_Float, ArgumentType_Double, ArgumentType_Integer, ArgumentType_Long, ArgumentType_String, ArgumentType_Entities, ArgumentType_Entity, ArgumentType_Players, ArgumentType_GameProfile, ArgumentType_BlockPos, ArgumentType_Position3d, ArgumentType_Position2d, ArgumentType_BlockState, ArgumentType_BlockPredicate, ArgumentType_Item, ArgumentType_ItemPredicate, ArgumentType_Component, ArgumentType_Rotation, ArgumentType_ResourceLocation, ArgumentType_EntityAnchor, ArgumentType_Gamemode, ArgumentType_Difficulty, ArgumentType_Time, ArgumentType_Resource]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_InvalidConsumption:
|
||||
value: Optional[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_InvalidRequirement:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_PermissionDenied:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_CommandFailed:
|
||||
value: text.TextComponent
|
||||
|
||||
|
||||
CommandError = Union[CommandError_InvalidConsumption, CommandError_InvalidRequirement, CommandError_PermissionDenied, CommandError_CommandFailed]
|
||||
|
||||
|
||||
class CommandNode:
|
||||
|
||||
@classmethod
|
||||
def literal(cls, name: str) -> Self:
|
||||
raise NotImplementedError
|
||||
@classmethod
|
||||
def argument(cls, name: str, arg_type: ArgumentType) -> Self:
|
||||
raise NotImplementedError
|
||||
def then(self, node: Self) -> None:
|
||||
raise NotImplementedError
|
||||
def execute_with_handler_id(self, handler_id: int) -> None:
|
||||
raise NotImplementedError
|
||||
def require_with_handler_id(self, handler_id: int) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Command:
|
||||
|
||||
def __init__(self, names: List[str], description: str) -> None:
|
||||
"""
|
||||
First name is primary, rest are aliases
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def then(self, node: CommandNode) -> None:
|
||||
raise NotImplementedError
|
||||
def execute_with_handler_id(self, handler_id: int) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
213
src/pumpkin_api/wit/wit_world/imports/common.py
Normal file
213
src/pumpkin_api/wit/wit_world/imports/common.py
Normal file
@ -0,0 +1,213 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Provides common types and utilities used across the entire plugin API.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class Hand(Enum):
|
||||
"""
|
||||
Represents the hands of a player.
|
||||
"""
|
||||
LEFT = 0
|
||||
RIGHT = 1
|
||||
|
||||
class GameMode(Enum):
|
||||
"""
|
||||
Represents the game modes available in Minecraft.
|
||||
"""
|
||||
SURVIVAL = 0
|
||||
CREATIVE = 1
|
||||
ADVENTURE = 2
|
||||
SPECTATOR = 3
|
||||
|
||||
class NamedColor(Enum):
|
||||
"""
|
||||
The 16 base Minecraft colors.
|
||||
"""
|
||||
BLACK = 0
|
||||
DARK_BLUE = 1
|
||||
DARK_GREEN = 2
|
||||
DARK_AQUA = 3
|
||||
DARK_RED = 4
|
||||
DARK_PURPLE = 5
|
||||
GOLD = 6
|
||||
GRAY = 7
|
||||
DARK_GRAY = 8
|
||||
BLUE = 9
|
||||
GREEN = 10
|
||||
AQUA = 11
|
||||
RED = 12
|
||||
LIGHT_PURPLE = 13
|
||||
YELLOW = 14
|
||||
WHITE = 15
|
||||
|
||||
@dataclass
|
||||
class RgbColor:
|
||||
"""
|
||||
An RGB color represented by its red, green, and blue components.
|
||||
"""
|
||||
r: int
|
||||
g: int
|
||||
b: int
|
||||
|
||||
@dataclass
|
||||
class ArgbColor:
|
||||
"""
|
||||
An ARGB color with alpha (transparency) channel.
|
||||
"""
|
||||
a: int
|
||||
r: int
|
||||
g: int
|
||||
b: int
|
||||
|
||||
@dataclass
|
||||
class ItemStack:
|
||||
"""
|
||||
Represents a stack of items with its type and count.
|
||||
"""
|
||||
registry_key: str
|
||||
count: int
|
||||
|
||||
class Locale(Enum):
|
||||
"""
|
||||
All Minecraft-supported locales.
|
||||
"""
|
||||
AF_ZA = 0
|
||||
AR_SA = 1
|
||||
AST_ES = 2
|
||||
AZ_AZ = 3
|
||||
BA_RU = 4
|
||||
BAR = 5
|
||||
BE_BY = 6
|
||||
BG_BG = 7
|
||||
BR_FR = 8
|
||||
BRB = 9
|
||||
BS_BA = 10
|
||||
CA_ES = 11
|
||||
CS_CZ = 12
|
||||
CY_GB = 13
|
||||
DA_DK = 14
|
||||
DE_AT = 15
|
||||
DE_CH = 16
|
||||
DE_DE = 17
|
||||
EL_GR = 18
|
||||
EN_AU = 19
|
||||
EN_CA = 20
|
||||
EN_GB = 21
|
||||
EN_NZ = 22
|
||||
EN_PT = 23
|
||||
EN_UD = 24
|
||||
EN_US = 25
|
||||
ENP = 26
|
||||
ENWS = 27
|
||||
EO_UY = 28
|
||||
ES_AR = 29
|
||||
ES_CL = 30
|
||||
ES_EC = 31
|
||||
ES_ES = 32
|
||||
ES_MX = 33
|
||||
ES_UY = 34
|
||||
ES_VE = 35
|
||||
ESAN = 36
|
||||
ET_EE = 37
|
||||
EU_ES = 38
|
||||
FA_IR = 39
|
||||
FI_FI = 40
|
||||
FIL_PH = 41
|
||||
FO_FO = 42
|
||||
FR_CA = 43
|
||||
FR_FR = 44
|
||||
FRA_DE = 45
|
||||
FUR_IT = 46
|
||||
FY_NL = 47
|
||||
GA_IE = 48
|
||||
GD_GB = 49
|
||||
GL_ES = 50
|
||||
HAW_US = 51
|
||||
HE_IL = 52
|
||||
HI_IN = 53
|
||||
HR_HR = 54
|
||||
HU_HU = 55
|
||||
HY_AM = 56
|
||||
ID_ID = 57
|
||||
IG_NG = 58
|
||||
IO_EN = 59
|
||||
IS_IS = 60
|
||||
ISV = 61
|
||||
IT_IT = 62
|
||||
JA_JP = 63
|
||||
JBO_EN = 64
|
||||
KA_GE = 65
|
||||
KK_KZ = 66
|
||||
KN_IN = 67
|
||||
KO_KR = 68
|
||||
KSH = 69
|
||||
KW_GB = 70
|
||||
LA_LA = 71
|
||||
LB_LU = 72
|
||||
LI_LI = 73
|
||||
LMO = 74
|
||||
LO_LA = 75
|
||||
LOL_US = 76
|
||||
LT_LT = 77
|
||||
LV_LV = 78
|
||||
LZH = 79
|
||||
MK_MK = 80
|
||||
MN_MN = 81
|
||||
MS_MY = 82
|
||||
MT_MT = 83
|
||||
NAH = 84
|
||||
NDS_DE = 85
|
||||
NL_BE = 86
|
||||
NL_NL = 87
|
||||
NN_NO = 88
|
||||
NO_NO = 89
|
||||
OC_FR = 90
|
||||
OVD = 91
|
||||
PL_PL = 92
|
||||
PT_BR = 93
|
||||
PT_PT = 94
|
||||
QYA_AA = 95
|
||||
RO_RO = 96
|
||||
RPR = 97
|
||||
RU_RU = 98
|
||||
RY_UA = 99
|
||||
SAH_SAH = 100
|
||||
SE_NO = 101
|
||||
SK_SK = 102
|
||||
SL_SI = 103
|
||||
SO_SO = 104
|
||||
SQ_AL = 105
|
||||
SR_CS = 106
|
||||
SR_SP = 107
|
||||
SV_SE = 108
|
||||
SXU = 109
|
||||
SZL = 110
|
||||
TA_IN = 111
|
||||
TH_TH = 112
|
||||
TL_PH = 113
|
||||
TLH_AA = 114
|
||||
TOK = 115
|
||||
TR_TR = 116
|
||||
TT_RU = 117
|
||||
UK_UA = 118
|
||||
VAL_ES = 119
|
||||
VEC_IT = 120
|
||||
VI_VN = 121
|
||||
YI_DE = 122
|
||||
YO_NG = 123
|
||||
ZH_CN = 124
|
||||
ZH_HK = 125
|
||||
ZH_TW = 126
|
||||
ZLM_ARAB = 127
|
||||
|
||||
|
||||
70
src/pumpkin_api/wit/wit_world/imports/context.py
Normal file
70
src/pumpkin_api/wit/wit_world/imports/context.py
Normal file
@ -0,0 +1,70 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
The core context provided to a plugin during initialization and event handling.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import permission
|
||||
from ..imports import event
|
||||
from ..imports import server
|
||||
from ..imports import command
|
||||
|
||||
class Context:
|
||||
"""
|
||||
A contextual handle for plugin-related operations.
|
||||
"""
|
||||
|
||||
def register_event(self, handler_id: int, event_type: event.EventType, event_priority: event.EventPriority, blocking: bool) -> None:
|
||||
"""
|
||||
Registers a handler for a specific event.
|
||||
|
||||
* `handler-id`: Unique ID for the event handler.
|
||||
* `event-type`: The type of event to listen for.
|
||||
* `event-priority`: When this handler should be called relative to others.
|
||||
* `blocking`: Whether the event should wait for this handler to finish.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def register_command(self, command: command.Command, permission: str) -> None:
|
||||
"""
|
||||
Registers a new command.
|
||||
|
||||
* `command`: The command definition.
|
||||
* `permission`: The required permission node to execute this command.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def register_permission(self, permission: permission.Permission) -> None:
|
||||
"""
|
||||
Registers a permission node with the server.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.str)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_data_folder(self) -> str:
|
||||
"""
|
||||
Returns the path to the plugin's private data folder.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_server(self) -> server.Server:
|
||||
"""
|
||||
Returns the global server instance.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
84
src/pumpkin_api/wit/wit_world/imports/entity.py
Normal file
84
src/pumpkin_api/wit/wit_world/imports/entity.py
Normal file
@ -0,0 +1,84 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class BlockEntity:
|
||||
|
||||
def resource_location(self) -> str:
|
||||
raise NotImplementedError
|
||||
def get_position(self) -> Tuple[int, int, int]:
|
||||
raise NotImplementedError
|
||||
def get_id(self) -> int:
|
||||
raise NotImplementedError
|
||||
def is_dirty(self) -> bool:
|
||||
"""
|
||||
write-nbt: func(nbt: nbt-compound);
|
||||
from-nbt: func(nbt: nbt-compound, position: block-position) -> entity;
|
||||
tick: func(world: simple-world);
|
||||
write-internal: func(nbt: nbt-compound);
|
||||
chunk-data-nbt: func() -> option<nbt-compound;
|
||||
get-inventory: func() -> option<inventory>;
|
||||
set-block-state: func(block-state: block-state-id);
|
||||
on-block-replaced: func(world: simple-world, position: block-position);
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def clear_dirty(self) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class CommandBlockEntity:
|
||||
|
||||
def get_block_entity(self) -> BlockEntity:
|
||||
raise NotImplementedError
|
||||
def last_output(self) -> str:
|
||||
raise NotImplementedError
|
||||
def track_output(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def success_count(self) -> int:
|
||||
raise NotImplementedError
|
||||
def command(self) -> str:
|
||||
raise NotImplementedError
|
||||
def auto(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def condition_met(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def powered(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Entity_CommandBlockEntity:
|
||||
value: CommandBlockEntity
|
||||
|
||||
|
||||
Entity = Union[Entity_CommandBlockEntity]
|
||||
|
||||
|
||||
|
||||
434
src/pumpkin_api/wit/wit_world/imports/event.py
Normal file
434
src/pumpkin_api/wit/wit_world/imports/event.py
Normal file
@ -0,0 +1,434 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import text
|
||||
from ..imports import world
|
||||
from ..imports import player
|
||||
|
||||
class EventPriority(Enum):
|
||||
HIGHEST = 0
|
||||
HIGH = 1
|
||||
NORMAL = 2
|
||||
LOW = 3
|
||||
LOWEST = 4
|
||||
|
||||
@dataclass
|
||||
class PlayerJoinEventData:
|
||||
player: player.Player
|
||||
join_message: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerLeaveEventData:
|
||||
player: player.Player
|
||||
leave_message: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerLoginEventData:
|
||||
player: player.Player
|
||||
kick_message: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerChatEventData:
|
||||
player: player.Player
|
||||
message: str
|
||||
recipients: List[player.Player]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerCommandSendEventData:
|
||||
player: player.Player
|
||||
command: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerPermissionCheckEventData:
|
||||
player: player.Player
|
||||
permission: str
|
||||
permission_result: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerMoveEventData:
|
||||
player: player.Player
|
||||
from_position: Tuple[float, float, float]
|
||||
to_position: Tuple[float, float, float]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerTeleportEventData:
|
||||
player: player.Player
|
||||
from_position: Tuple[float, float, float]
|
||||
to_position: Tuple[float, float, float]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerChangeWorldEventData:
|
||||
player: player.Player
|
||||
previous_world: world.World
|
||||
new_world: world.World
|
||||
position: Tuple[float, float, float]
|
||||
yaw: float
|
||||
pitch: float
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerExpChangeEventData:
|
||||
player: player.Player
|
||||
amount: int
|
||||
|
||||
@dataclass
|
||||
class PlayerItemHeldEventData:
|
||||
player: player.Player
|
||||
previous_slot: int
|
||||
new_slot: int
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerChangedMainHandEventData:
|
||||
player: player.Player
|
||||
main_hand: common.Hand
|
||||
|
||||
@dataclass
|
||||
class PlayerGamemodeChangeEventData:
|
||||
player: player.Player
|
||||
previous_gamemode: common.GameMode
|
||||
new_gamemode: common.GameMode
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerCustomPayloadEventData:
|
||||
player: player.Player
|
||||
channel: str
|
||||
data: bytes
|
||||
|
||||
class PlayerFishState(Enum):
|
||||
FISHING = 0
|
||||
CAUGHT_FISH = 1
|
||||
CAUGHT_ENTITY = 2
|
||||
IN_GROUND = 3
|
||||
FAILED_ATTEMPT = 4
|
||||
REEL_IN = 5
|
||||
BITE = 6
|
||||
|
||||
@dataclass
|
||||
class PlayerFishEventData:
|
||||
player: player.Player
|
||||
caught_uuid: Optional[str]
|
||||
caught_type: str
|
||||
hook_uuid: str
|
||||
state: PlayerFishState
|
||||
hand: common.Hand
|
||||
exp_to_drop: int
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerEggThrowEventData:
|
||||
player: player.Player
|
||||
egg_uuid: str
|
||||
hatching: bool
|
||||
num_hatches: int
|
||||
hatching_type: str
|
||||
cancelled: bool
|
||||
|
||||
class EntityInteractionAction(Enum):
|
||||
INTERACT = 0
|
||||
ATTACK = 1
|
||||
INTERACT_AT = 2
|
||||
|
||||
class InteractAction(Enum):
|
||||
LEFT_CLICK_BLOCK = 0
|
||||
LEFT_CLICK_AIR = 1
|
||||
RIGHT_CLICK_AIR = 2
|
||||
RIGHT_CLICK_BLOCK = 3
|
||||
|
||||
@dataclass
|
||||
class PlayerInteractEventData:
|
||||
player: player.Player
|
||||
action: InteractAction
|
||||
clicked_pos: Optional[Tuple[int, int, int]]
|
||||
item: common.ItemStack
|
||||
block: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerToggleSneakEventData:
|
||||
player: player.Player
|
||||
is_sneaking: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerToggleSprintEventData:
|
||||
player: player.Player
|
||||
is_sprinting: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerInteractUnknownEntityEventData:
|
||||
player: player.Player
|
||||
entity_id: int
|
||||
action: EntityInteractionAction
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockRedstoneEventData:
|
||||
target_world: world.World
|
||||
state_id: int
|
||||
block_position: Tuple[int, int, int]
|
||||
old_current: int
|
||||
new_current: int
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockBreakEventData:
|
||||
player: Optional[player.Player]
|
||||
block: str
|
||||
block_position: Tuple[int, int, int]
|
||||
exp: int
|
||||
should_drop: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockBurnEventData:
|
||||
igniting_block: str
|
||||
block: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockCanBuildEventData:
|
||||
block_to_build: str
|
||||
buildable: bool
|
||||
player: player.Player
|
||||
block: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockGrowEventData:
|
||||
target_world: world.World
|
||||
old_block: str
|
||||
old_state_id: int
|
||||
new_block: str
|
||||
new_state_id: int
|
||||
block_position: Tuple[int, int, int]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockPlaceEventData:
|
||||
player: player.Player
|
||||
block_placed: str
|
||||
block_placed_against: str
|
||||
block_position: Tuple[int, int, int]
|
||||
can_build: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class ServerCommandEventData:
|
||||
command: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class SpawnChangeEventData:
|
||||
target_world: world.World
|
||||
previous_position: Tuple[int, int, int]
|
||||
previous_yaw: float
|
||||
previous_pitch: float
|
||||
new_position: Tuple[int, int, int]
|
||||
new_yaw: float
|
||||
new_pitch: float
|
||||
|
||||
@dataclass
|
||||
class ServerBroadcastEventData:
|
||||
message: text.TextComponent
|
||||
sender: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
class EventType(Enum):
|
||||
PLAYER_JOIN_EVENT = 0
|
||||
PLAYER_LEAVE_EVENT = 1
|
||||
PLAYER_LOGIN_EVENT = 2
|
||||
PLAYER_CHAT_EVENT = 3
|
||||
PLAYER_COMMAND_SEND_EVENT = 4
|
||||
PLAYER_PERMISSION_CHECK_EVENT = 5
|
||||
PLAYER_MOVE_EVENT = 6
|
||||
PLAYER_TELEPORT_EVENT = 7
|
||||
PLAYER_CHANGE_WORLD_EVENT = 8
|
||||
PLAYER_EXP_CHANGE_EVENT = 9
|
||||
PLAYER_ITEM_HELD_EVENT = 10
|
||||
PLAYER_CHANGED_MAIN_HAND_EVENT = 11
|
||||
PLAYER_GAMEMODE_CHANGE_EVENT = 12
|
||||
PLAYER_CUSTOM_PAYLOAD_EVENT = 13
|
||||
PLAYER_FISH_EVENT = 14
|
||||
PLAYER_EGG_THROW_EVENT = 15
|
||||
PLAYER_INTERACT_UNKNOWN_ENTITY_EVENT = 16
|
||||
PLAYER_INTERACT_EVENT = 17
|
||||
PLAYER_TOGGLE_SNEAK_EVENT = 18
|
||||
PLAYER_TOGGLE_SPRINT_EVENT = 19
|
||||
BLOCK_REDSTONE_EVENT = 20
|
||||
BLOCK_BREAK_EVENT = 21
|
||||
BLOCK_BURN_EVENT = 22
|
||||
BLOCK_CAN_BUILD_EVENT = 23
|
||||
BLOCK_GROW_EVENT = 24
|
||||
BLOCK_PLACE_EVENT = 25
|
||||
SERVER_COMMAND_EVENT = 26
|
||||
SPAWN_CHANGE_EVENT = 27
|
||||
SERVER_BROADCAST_EVENT = 28
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerJoinEvent:
|
||||
value: PlayerJoinEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerLeaveEvent:
|
||||
value: PlayerLeaveEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerLoginEvent:
|
||||
value: PlayerLoginEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerChatEvent:
|
||||
value: PlayerChatEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerCommandSendEvent:
|
||||
value: PlayerCommandSendEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerPermissionCheckEvent:
|
||||
value: PlayerPermissionCheckEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerMoveEvent:
|
||||
value: PlayerMoveEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerTeleportEvent:
|
||||
value: PlayerTeleportEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerChangeWorldEvent:
|
||||
value: PlayerChangeWorldEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerExpChangeEvent:
|
||||
value: PlayerExpChangeEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerItemHeldEvent:
|
||||
value: PlayerItemHeldEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerChangedMainHandEvent:
|
||||
value: PlayerChangedMainHandEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerGamemodeChangeEvent:
|
||||
value: PlayerGamemodeChangeEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerCustomPayloadEvent:
|
||||
value: PlayerCustomPayloadEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerFishEvent:
|
||||
value: PlayerFishEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerEggThrowEvent:
|
||||
value: PlayerEggThrowEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerInteractUnknownEntityEvent:
|
||||
value: PlayerInteractUnknownEntityEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerInteractEvent:
|
||||
value: PlayerInteractEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerToggleSneakEvent:
|
||||
value: PlayerToggleSneakEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerToggleSprintEvent:
|
||||
value: PlayerToggleSprintEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockRedstoneEvent:
|
||||
value: BlockRedstoneEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockBreakEvent:
|
||||
value: BlockBreakEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockBurnEvent:
|
||||
value: BlockBurnEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockCanBuildEvent:
|
||||
value: BlockCanBuildEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockGrowEvent:
|
||||
value: BlockGrowEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockPlaceEvent:
|
||||
value: BlockPlaceEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_ServerCommandEvent:
|
||||
value: ServerCommandEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_SpawnChangeEvent:
|
||||
value: SpawnChangeEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_ServerBroadcastEvent:
|
||||
value: ServerBroadcastEventData
|
||||
|
||||
|
||||
Event = Union[Event_PlayerJoinEvent, Event_PlayerLeaveEvent, Event_PlayerLoginEvent, Event_PlayerChatEvent, Event_PlayerCommandSendEvent, Event_PlayerPermissionCheckEvent, Event_PlayerMoveEvent, Event_PlayerTeleportEvent, Event_PlayerChangeWorldEvent, Event_PlayerExpChangeEvent, Event_PlayerItemHeldEvent, Event_PlayerChangedMainHandEvent, Event_PlayerGamemodeChangeEvent, Event_PlayerCustomPayloadEvent, Event_PlayerFishEvent, Event_PlayerEggThrowEvent, Event_PlayerInteractUnknownEntityEvent, Event_PlayerInteractEvent, Event_PlayerToggleSneakEvent, Event_PlayerToggleSprintEvent, Event_BlockRedstoneEvent, Event_BlockBreakEvent, Event_BlockBurnEvent, Event_BlockCanBuildEvent, Event_BlockGrowEvent, Event_BlockPlaceEvent, Event_ServerCommandEvent, Event_SpawnChangeEvent, Event_ServerBroadcastEvent]
|
||||
|
||||
|
||||
|
||||
61
src/pumpkin_api/wit/wit_world/imports/gui.py
Normal file
61
src/pumpkin_api/wit/wit_world/imports/gui.py
Normal file
@ -0,0 +1,61 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import text
|
||||
|
||||
class GuiType(Enum):
|
||||
GENERIC_9X1 = 0
|
||||
GENERIC_9X2 = 1
|
||||
GENERIC_9X3 = 2
|
||||
GENERIC_9X4 = 3
|
||||
GENERIC_9X5 = 4
|
||||
GENERIC_9X6 = 5
|
||||
GENERIC_3X3 = 6
|
||||
CRAFTER_3X3 = 7
|
||||
ANVIL = 8
|
||||
BEACON = 9
|
||||
BLAST_FURNACE = 10
|
||||
BREWING_STAND = 11
|
||||
CRAFTING = 12
|
||||
ENCHANTMENT = 13
|
||||
FURNACE = 14
|
||||
GRINDSTONE = 15
|
||||
HOPPER = 16
|
||||
LECTERN = 17
|
||||
LOOM = 18
|
||||
MERCHANT = 19
|
||||
SHULKER_BOX = 20
|
||||
SMITHING = 21
|
||||
SMOKER = 22
|
||||
CARTOGRAPHY_TABLE = 23
|
||||
STONECUTTER = 24
|
||||
|
||||
class Gui:
|
||||
|
||||
def __init__(self, type: GuiType, title: text.TextComponent) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_item(self, slot: int, item: common.ItemStack) -> None:
|
||||
raise NotImplementedError
|
||||
def get_item(self, slot: int) -> Optional[common.ItemStack]:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
35
src/pumpkin_api/wit/wit_world/imports/i18n.py
Normal file
35
src/pumpkin_api/wit/wit_world/imports/i18n.py
Normal file
@ -0,0 +1,35 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
|
||||
|
||||
def translate(key: str, locale: common.Locale) -> str:
|
||||
"""
|
||||
Retrieves a translated string from the host.
|
||||
|
||||
# Arguments
|
||||
* `key`: The namespaced translation key (e.g. `pumpkin:my_key`).
|
||||
* `locale`: The target locale.
|
||||
|
||||
# Returns
|
||||
The localized string, falling back to English or the key itself.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def load_translations(namespace: str, json: str, locale: common.Locale) -> None:
|
||||
"""
|
||||
Loads custom translations from a JSON string.
|
||||
|
||||
# Arguments
|
||||
* `namespace`: The namespace to associate these keys with.
|
||||
* `json`: A JSON string containing a flat map of translations.
|
||||
* `locale`: The target locale for these translations.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
30
src/pumpkin_api/wit/wit_world/imports/logging.py
Normal file
30
src/pumpkin_api/wit/wit_world/imports/logging.py
Normal file
@ -0,0 +1,30 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class Level(Enum):
|
||||
TRACE = 0
|
||||
DEBUG = 1
|
||||
INFO = 2
|
||||
WARN = 3
|
||||
ERROR = 4
|
||||
|
||||
|
||||
def log(level: Level, message: str) -> None:
|
||||
"""
|
||||
log any general purpose message
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def log_tracing(event: bytes) -> None:
|
||||
"""
|
||||
This function is meant to be used by the tracing crate.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
71
src/pumpkin_api/wit/wit_world/imports/permission.py
Normal file
71
src/pumpkin_api/wit/wit_world/imports/permission.py
Normal file
@ -0,0 +1,71 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class PermissionLevel(Enum):
|
||||
"""
|
||||
Represents the player's permission level
|
||||
|
||||
Permission levels determine the player's access to commands and server operations.
|
||||
Each numeric level corresponds to a specific role:
|
||||
- `Zero`: `normal`: Player can use basic commands.
|
||||
- `One`: `moderator`: Player can bypass spawn protection.
|
||||
- `Two`: `gamemaster`: Player or executor can use more commands and player can use command blocks.
|
||||
- `Three`: `admin`: Player or executor can use commands related to multiplayer management.
|
||||
- `Four`: `owner`: Player or executor can use all of the commands, including commands related to server management.
|
||||
"""
|
||||
ZERO = 0
|
||||
ONE = 1
|
||||
TWO = 2
|
||||
THREE = 3
|
||||
FOUR = 4
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionDefault_Deny:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionDefault_Allow:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionDefault_Op:
|
||||
value: PermissionLevel
|
||||
|
||||
|
||||
PermissionDefault = Union[PermissionDefault_Deny, PermissionDefault_Allow, PermissionDefault_Op]
|
||||
"""
|
||||
Describes the default behavior for permissions
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionChild:
|
||||
"""
|
||||
A child permission entry
|
||||
"""
|
||||
node: str
|
||||
value: bool
|
||||
|
||||
@dataclass
|
||||
class Permission:
|
||||
"""
|
||||
Defines a permission node in the system
|
||||
"""
|
||||
node: str
|
||||
description: str
|
||||
default: PermissionDefault
|
||||
children: List[PermissionChild]
|
||||
|
||||
|
||||
350
src/pumpkin_api/wit/wit_world/imports/player.py
Normal file
350
src/pumpkin_api/wit/wit_world/imports/player.py
Normal file
@ -0,0 +1,350 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Represents a player connected to the Minecraft server.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import permission
|
||||
from ..imports import text
|
||||
from ..imports import gui
|
||||
from ..imports import world
|
||||
|
||||
@dataclass
|
||||
class PlayerAbilities:
|
||||
"""
|
||||
Various abilities a player can have.
|
||||
"""
|
||||
invulnerable: bool
|
||||
flying: bool
|
||||
allow_flying: bool
|
||||
creative: bool
|
||||
allow_modify_world: bool
|
||||
fly_speed: float
|
||||
walk_speed: float
|
||||
|
||||
class Player:
|
||||
"""
|
||||
A handle to a player on the server.
|
||||
"""
|
||||
|
||||
def get_id(self) -> str:
|
||||
"""
|
||||
Returns the player's unique UUID as a string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Returns the player's username.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_position(self) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Basic state
|
||||
Returns the player's current position in the world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_yaw(self) -> float:
|
||||
"""
|
||||
Returns the player's current yaw (horizontal rotation).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_pitch(self) -> float:
|
||||
"""
|
||||
Returns the player's current pitch (vertical rotation).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_world(self) -> world.World:
|
||||
"""
|
||||
Returns the world the player is currently in.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_gamemode(self) -> common.GameMode:
|
||||
"""
|
||||
Returns the player's current game mode.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_gamemode(self, mode: common.GameMode) -> bool:
|
||||
"""
|
||||
Changes the player's game mode. Returns true if successful.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_locale(self) -> str:
|
||||
"""
|
||||
Returns the player's locale (e.g., "en_us").
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_ping(self) -> int:
|
||||
"""
|
||||
Returns the player's current ping in milliseconds.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_permission_level(self) -> permission.PermissionLevel:
|
||||
"""
|
||||
Permissions & metadata
|
||||
Returns the player's permission level (0-4).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_permission_level(self, level: permission.PermissionLevel) -> None:
|
||||
"""
|
||||
Sets the player's permission level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def has_permission(self, node: str) -> bool:
|
||||
"""
|
||||
Checks if the player has a specific permission node.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_display_name(self) -> text.TextComponent:
|
||||
"""
|
||||
Returns the player's display name, which may include formatting.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def send_system_message(self, text: text.TextComponent, overlay: bool) -> None:
|
||||
"""
|
||||
Messaging & titles
|
||||
Sends a system message to the player's chat.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def show_title(self, text: text.TextComponent) -> None:
|
||||
"""
|
||||
Shows a large title on the player's screen.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def show_subtitle(self, text: text.TextComponent) -> None:
|
||||
"""
|
||||
Shows a smaller subtitle on the player's screen.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def show_actionbar(self, text: text.TextComponent) -> None:
|
||||
"""
|
||||
Shows a message in the action bar area.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def send_title_animation(self, fade_in: int, stay: int, fade_out: int) -> None:
|
||||
"""
|
||||
Sets the fade-in, stay, and fade-out times for titles.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def teleport(self, position: Tuple[float, float, float], yaw: Optional[float], pitch: Optional[float], world: world.World) -> None:
|
||||
"""
|
||||
Teleport & kick
|
||||
Teleports the player to a position in a world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def teleport_world(self, world_ref: world.World, position: Tuple[float, float, float], yaw: Optional[float], pitch: Optional[float]) -> None:
|
||||
"""
|
||||
Teleports the player to another world at a specific position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def kick(self, message: text.TextComponent) -> None:
|
||||
"""
|
||||
Kicks the player from the server with the specified reason.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def respawn(self) -> None:
|
||||
"""
|
||||
Forces the player to respawn.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def open_gui(self, gui_ref: gui.Gui) -> None:
|
||||
"""
|
||||
Opens a GUI for the player.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def ban(self, reason: Optional[text.TextComponent]) -> None:
|
||||
"""
|
||||
Bans the player with an optional reason.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def ban_ip(self, reason: Optional[text.TextComponent]) -> None:
|
||||
"""
|
||||
Bans the player's IP address with an optional reason.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_selected_slot(self) -> int:
|
||||
"""
|
||||
Inventory
|
||||
Returns the index of the currently selected hotbar slot (0-8).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_item_in_hand(self, hand: common.Hand) -> Optional[common.ItemStack]:
|
||||
"""
|
||||
Returns the item currently in the specified hand.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_inventory_item(self, slot: int) -> Optional[common.ItemStack]:
|
||||
"""
|
||||
Returns the item in the specified inventory slot.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_health(self) -> float:
|
||||
"""
|
||||
Status
|
||||
Returns the player's current health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_health(self, health: float) -> None:
|
||||
"""
|
||||
Sets the player's current health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_max_health(self) -> float:
|
||||
"""
|
||||
Returns the player's maximum health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_max_health(self, max_health: float) -> None:
|
||||
"""
|
||||
Sets the player's maximum health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_food_level(self) -> int:
|
||||
"""
|
||||
Returns the player's food level (0-20).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_food_level(self, food_level: int) -> None:
|
||||
"""
|
||||
Sets the player's food level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_saturation(self) -> float:
|
||||
"""
|
||||
Returns the player's food saturation level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_saturation(self, saturation: float) -> None:
|
||||
"""
|
||||
Sets the player's food saturation level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_exhaustion(self) -> float:
|
||||
"""
|
||||
Returns the player's food exhaustion level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_exhaustion(self, exhaustion: float) -> None:
|
||||
"""
|
||||
Sets the player's food exhaustion level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_absorption(self) -> float:
|
||||
"""
|
||||
Returns the player's current absorption amount.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_absorption(self, absorption: float) -> None:
|
||||
"""
|
||||
Sets the player's current absorption amount.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_experience_level(self) -> int:
|
||||
"""
|
||||
Returns the player's total experience level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_experience_progress(self) -> float:
|
||||
"""
|
||||
Returns the player's progress toward the next level (0.0 to 1.0).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_experience_points(self) -> int:
|
||||
"""
|
||||
Returns the total experience points the player has.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_experience_level(self, level: int) -> None:
|
||||
"""
|
||||
Sets the player's total experience level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_experience_progress(self, progress: float) -> None:
|
||||
"""
|
||||
Sets the player's progress toward the next level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_experience_points(self, points: int) -> None:
|
||||
"""
|
||||
Sets the player's total experience points.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def add_experience_levels(self, levels: int) -> None:
|
||||
"""
|
||||
Adds experience levels to the player.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def add_experience_points(self, points: int) -> None:
|
||||
"""
|
||||
Adds experience points to the player.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_sneaking(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently sneaking.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_sneaking(self, sneaking: bool) -> None:
|
||||
"""
|
||||
Sets whether the player is currently sneaking.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_sprinting(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently sprinting.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_sprinting(self, sprinting: bool) -> None:
|
||||
"""
|
||||
Sets whether the player is currently sprinting.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_on_ground(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently on the ground.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_flying(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently flying.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_flying(self, flying: bool) -> None:
|
||||
"""
|
||||
Sets whether the player should be flying.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_abilities(self) -> PlayerAbilities:
|
||||
"""
|
||||
Returns the player's current abilities.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_abilities(self, abilities: PlayerAbilities) -> None:
|
||||
"""
|
||||
Updates the player's abilities.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_ip(self) -> str:
|
||||
"""
|
||||
Returns the player's IP address.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
44
src/pumpkin_api/wit/wit_world/imports/scheduler.py
Normal file
44
src/pumpkin_api/wit/wit_world/imports/scheduler.py
Normal file
@ -0,0 +1,44 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Provides functionality to schedule tasks to be executed later on the server.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
|
||||
def schedule_delayed_task(handler_id: int, delay_ticks: int) -> int:
|
||||
"""
|
||||
Schedules a task to be executed once after the specified number of ticks.
|
||||
|
||||
* `handler-id`: The unique ID of the handler to call when the task executes.
|
||||
* `delay-ticks`: The number of game ticks to wait before execution (20 ticks = 1 second).
|
||||
|
||||
Returns a unique task ID that can be used to cancel the task.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def schedule_repeating_task(handler_id: int, delay_ticks: int, period_ticks: int) -> int:
|
||||
"""
|
||||
Schedules a task to be executed repeatedly.
|
||||
|
||||
* `handler-id`: The unique ID of the handler to call when the task executes.
|
||||
* `delay-ticks`: The number of game ticks to wait before the first execution.
|
||||
* `period-ticks`: The number of game ticks between subsequent executions.
|
||||
|
||||
Returns a unique task ID that can be used to cancel the task.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def cancel_task(task_id: int) -> None:
|
||||
"""
|
||||
Cancels a scheduled task if it hasn't finished yet.
|
||||
|
||||
* `task-id`: The ID of the task to cancel.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
95
src/pumpkin_api/wit/wit_world/imports/scoreboard.py
Normal file
95
src/pumpkin_api/wit/wit_world/imports/scoreboard.py
Normal file
@ -0,0 +1,95 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import text
|
||||
|
||||
class RenderType(Enum):
|
||||
INTEGER = 0
|
||||
HEARTS = 1
|
||||
|
||||
class DisplaySlot(Enum):
|
||||
PLAYER_LIST = 0
|
||||
SIDEBAR = 1
|
||||
BELOW_NAME = 2
|
||||
SIDEBAR_TEAM_BLACK = 3
|
||||
SIDEBAR_TEAM_DARK_BLUE = 4
|
||||
SIDEBAR_TEAM_DARK_GREEN = 5
|
||||
SIDEBAR_TEAM_DARK_AQUA = 6
|
||||
SIDEBAR_TEAM_DARK_RED = 7
|
||||
SIDEBAR_TEAM_DARK_PURPLE = 8
|
||||
SIDEBAR_TEAM_GOLD = 9
|
||||
SIDEBAR_TEAM_GRAY = 10
|
||||
SIDEBAR_TEAM_DARK_GRAY = 11
|
||||
SIDEBAR_TEAM_BLUE = 12
|
||||
SIDEBAR_TEAM_GREEN = 13
|
||||
SIDEBAR_TEAM_AQUA = 14
|
||||
SIDEBAR_TEAM_RED = 15
|
||||
SIDEBAR_TEAM_LIGHT_PURPLE = 16
|
||||
SIDEBAR_TEAM_YELLOW = 17
|
||||
SIDEBAR_TEAM_WHITE = 18
|
||||
|
||||
class NametagVisibility(Enum):
|
||||
ALWAYS = 0
|
||||
NEVER = 1
|
||||
HIDE_FOR_OTHER_TEAMS = 2
|
||||
HIDE_FOR_OWN_TEAM = 3
|
||||
|
||||
class CollisionRule(Enum):
|
||||
ALWAYS = 0
|
||||
NEVER = 1
|
||||
PUSH_OTHER_TEAMS = 2
|
||||
PUSH_OWN_TEAM = 3
|
||||
|
||||
@dataclass
|
||||
class TeamSettings:
|
||||
display_name: text.TextComponent
|
||||
friendly_fire: bool
|
||||
see_friendly_invisibles: bool
|
||||
nametag_visibility: NametagVisibility
|
||||
collision_rule: CollisionRule
|
||||
color: common.NamedColor
|
||||
prefix: text.TextComponent
|
||||
suffix: text.TextComponent
|
||||
|
||||
class Scoreboard:
|
||||
|
||||
def add_objective(self, name: str, display_name: text.TextComponent, render_type: RenderType) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_objective(self, name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def set_display_slot(self, slot: DisplaySlot, objective_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def update_score(self, entity_name: str, objective_name: str, value: int) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_score(self, entity_name: str, objective_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def create_team(self, name: str, settings: TeamSettings) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_team(self, name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def update_team(self, name: str, settings: TeamSettings) -> None:
|
||||
raise NotImplementedError
|
||||
def add_player_to_team(self, team_name: str, player_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_player_from_team(self, team_name: str, player_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
75
src/pumpkin_api/wit/wit_world/imports/server.py
Normal file
75
src/pumpkin_api/wit/wit_world/imports/server.py
Normal file
@ -0,0 +1,75 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import player
|
||||
|
||||
class Difficulty(Enum):
|
||||
"""
|
||||
Represents the difficulty setting of a Minecraft server.
|
||||
"""
|
||||
PEACEFUL = 0
|
||||
EASY = 1
|
||||
NORMAL = 2
|
||||
HARD = 3
|
||||
|
||||
class Server:
|
||||
"""
|
||||
Represents the global server instance.
|
||||
"""
|
||||
|
||||
def get_difficulty(self) -> Difficulty:
|
||||
"""
|
||||
Returns the current difficulty level of the server.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_player_count(self) -> int:
|
||||
"""
|
||||
Returns the total number of players currently connected to the server.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_mspt(self) -> float:
|
||||
"""
|
||||
Returns the rolling average Milliseconds Per Tick (MSPT).
|
||||
A value below 50.0 is required for a stable 20 TPS.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_tps(self) -> float:
|
||||
"""
|
||||
Returns the effective Ticks Per Second (TPS).
|
||||
Ideal value is 20.0.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_all_players(self) -> List[player.Player]:
|
||||
"""
|
||||
Returns a list of all online players across all worlds.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_player_by_name(self, name: str) -> Optional[player.Player]:
|
||||
"""
|
||||
Searches for a player by their exact name.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_player_by_uuid(self, id: str) -> Optional[player.Player]:
|
||||
"""
|
||||
Searches for a player by their UUID string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
89
src/pumpkin_api/wit/wit_world/imports/text.py
Normal file
89
src/pumpkin_api/wit/wit_world/imports/text.py
Normal file
@ -0,0 +1,89 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
|
||||
class TextComponent:
|
||||
|
||||
@classmethod
|
||||
def text(cls, plain: str) -> Self:
|
||||
raise NotImplementedError
|
||||
@classmethod
|
||||
def translate(cls, key: str, with_: List[Self]) -> Self:
|
||||
raise NotImplementedError
|
||||
def add_child(self, child: Self) -> None:
|
||||
raise NotImplementedError
|
||||
def add_text(self, text: str) -> None:
|
||||
raise NotImplementedError
|
||||
def get_text(self) -> str:
|
||||
raise NotImplementedError
|
||||
def encode(self) -> bytes:
|
||||
raise NotImplementedError
|
||||
def color_named(self, color: common.NamedColor) -> None:
|
||||
"""
|
||||
Style
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def color_rgb(self, color: common.RgbColor) -> None:
|
||||
raise NotImplementedError
|
||||
def bold(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def italic(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def underlined(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def strikethrough(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def obfuscated(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def insertion(self, text: str) -> None:
|
||||
"""
|
||||
Text inserted into chat when shift-clicked
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def font(self, font: str) -> None:
|
||||
raise NotImplementedError
|
||||
def shadow_color(self, color: common.ArgbColor) -> None:
|
||||
raise NotImplementedError
|
||||
def click_open_url(self, url: str) -> None:
|
||||
"""
|
||||
Click events
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def click_run_command(self, command: str) -> None:
|
||||
raise NotImplementedError
|
||||
def click_suggest_command(self, command: str) -> None:
|
||||
raise NotImplementedError
|
||||
def click_copy_to_clipboard(self, text: str) -> None:
|
||||
raise NotImplementedError
|
||||
def hover_show_text(self, text: Self) -> None:
|
||||
"""
|
||||
Hover events
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def hover_show_item(self, item: str) -> None:
|
||||
"""
|
||||
Item data as SNBT string
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def hover_show_entity(self, entity_type: str, id: str, name: Optional[Self]) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
215
src/pumpkin_api/wit/wit_world/imports/world.py
Normal file
215
src/pumpkin_api/wit/wit_world/imports/world.py
Normal file
@ -0,0 +1,215 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import text
|
||||
from ..imports import scoreboard
|
||||
|
||||
class PistonBehavior(Enum):
|
||||
"""
|
||||
Defines how a block reacts when pushed by a piston.
|
||||
"""
|
||||
NORMAL = 0
|
||||
DESTROY = 1
|
||||
BLOCK = 2
|
||||
IGNORE = 3
|
||||
PUSH_ONLY = 4
|
||||
|
||||
class SoundCategory(Enum):
|
||||
"""
|
||||
Categories for sounds to control their volume independently.
|
||||
"""
|
||||
MASTER = 0
|
||||
MUSIC = 1
|
||||
RECORDS = 2
|
||||
WEATHER = 3
|
||||
BLOCKS = 4
|
||||
HOSTILE = 5
|
||||
NEUTRAL = 6
|
||||
PLAYERS = 7
|
||||
AMBIENT = 8
|
||||
VOICE = 9
|
||||
|
||||
class ExplosionInteraction(Enum):
|
||||
"""
|
||||
Defines how an explosion interacts with blocks in the world.
|
||||
"""
|
||||
NONE = 0
|
||||
BLOCK = 1
|
||||
MOB = 2
|
||||
TNT = 3
|
||||
TRIGGER = 4
|
||||
|
||||
class BlockFlags(Flag):
|
||||
"""
|
||||
Flags used to control block updates and notifications.
|
||||
"""
|
||||
NOTIFY_NEIGHBORS = auto()
|
||||
NOTIFY_LISTENERS = auto()
|
||||
FORCE_STATE = auto()
|
||||
SKIP_DROPS = auto()
|
||||
MOVED = auto()
|
||||
SKIP_REDSTONE_WIRE_STATE_REPLACEMENT = auto()
|
||||
SKIP_BLOCK_ENTITY_REPLACED_CALLBACK = auto()
|
||||
SKIP_BLOCK_ADDED_CALLBACK = auto()
|
||||
|
||||
@dataclass
|
||||
class BlockState:
|
||||
"""
|
||||
Detailed information about a block's state.
|
||||
"""
|
||||
id: int
|
||||
luminance: int
|
||||
opacity: int
|
||||
hardness: float
|
||||
is_air: bool
|
||||
is_liquid: bool
|
||||
is_solid: bool
|
||||
is_full_cube: bool
|
||||
piston_behavior: PistonBehavior
|
||||
has_random_ticks: bool
|
||||
|
||||
@dataclass
|
||||
class BlockStateId:
|
||||
"""
|
||||
A simple wrapper for a block state ID.
|
||||
"""
|
||||
id: int
|
||||
|
||||
@dataclass
|
||||
class BlockPos:
|
||||
"""
|
||||
A position in the world grid.
|
||||
"""
|
||||
x: int
|
||||
y: int
|
||||
z: int
|
||||
|
||||
class World:
|
||||
"""
|
||||
Represents a Minecraft world (dimension).
|
||||
"""
|
||||
|
||||
def get_id(self) -> str:
|
||||
"""
|
||||
Returns the unique identifier of this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_block_state_id(self, pos: BlockPos) -> int:
|
||||
"""
|
||||
Gets the block state ID at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_block_state(self, pos: BlockPos) -> BlockState:
|
||||
"""
|
||||
Gets detailed block state information at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_block_state(self, pos: BlockPos, state: int, update_flags: BlockFlags) -> None:
|
||||
"""
|
||||
Sets the block state at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_time_of_day(self) -> int:
|
||||
"""
|
||||
Returns the current time of day in ticks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_time_of_day(self, time: int) -> None:
|
||||
"""
|
||||
Sets the current time of day in ticks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_world_age(self) -> int:
|
||||
"""
|
||||
Returns the total age of the world in ticks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_dimension(self) -> str:
|
||||
"""
|
||||
Returns the dimension type (e.g., "minecraft:overworld").
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_top_block_y(self, x: int, z: int) -> int:
|
||||
"""
|
||||
Gets the highest non-air block Y coordinate at the specified X and Z.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_motion_blocking_height(self, x: int, z: int) -> int:
|
||||
"""
|
||||
Gets the highest motion-blocking block Y coordinate.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_raining(self) -> bool:
|
||||
"""
|
||||
Returns whether it is currently raining or snowing.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_raining(self, raining: bool) -> None:
|
||||
"""
|
||||
Sets whether it should be raining or snowing.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_thundering(self) -> bool:
|
||||
"""
|
||||
Returns whether there is currently a thunderstorm.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_thundering(self, thundering: bool) -> None:
|
||||
"""
|
||||
Sets whether there should be a thunderstorm.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def broadcast_system_message(self, message: text.TextComponent, overlay: bool) -> None:
|
||||
"""
|
||||
Broadcasts a system message to all players in this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_scoreboard(self) -> scoreboard.Scoreboard:
|
||||
"""
|
||||
Returns the scoreboard associated with this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def play_sound(self, sound: str, category: SoundCategory, pos: Tuple[float, float, float], volume: float, pitch: float) -> None:
|
||||
"""
|
||||
Plays a sound at the specified position for all players in the world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def spawn_particle(self, particle: str, pos: Tuple[float, float, float], offset: Tuple[float, float, float], max_speed: float, count: int) -> None:
|
||||
"""
|
||||
Spawns particles at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def create_explosion(self, pos: Tuple[float, float, float], power: float, create_fire: bool, interaction: ExplosionInteraction) -> None:
|
||||
"""
|
||||
Creates an explosion at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_sea_level(self) -> int:
|
||||
"""
|
||||
Returns the sea level of this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_min_y(self) -> int:
|
||||
"""
|
||||
Returns the minimum Y coordinate (bottom of the world).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
189
src/pumpkin_api/wit_files/command.wit
Normal file
189
src/pumpkin_api/wit_files/command.wit
Normal file
@ -0,0 +1,189 @@
|
||||
interface command {
|
||||
use player.{player};
|
||||
use %world.{%world};
|
||||
use entity.{command-block-entity, entity};
|
||||
use common.{position, block-position, locale};
|
||||
use server.{server, difficulty};
|
||||
use text.{text-component};
|
||||
|
||||
enum gamemode {
|
||||
survival,
|
||||
creative,
|
||||
adventure,
|
||||
spectator,
|
||||
}
|
||||
|
||||
enum bossbar-color {
|
||||
pink,
|
||||
blue,
|
||||
red,
|
||||
green,
|
||||
yellow,
|
||||
purple,
|
||||
white,
|
||||
}
|
||||
|
||||
enum bossbar-style {
|
||||
no-division,
|
||||
notches6,
|
||||
notches10,
|
||||
notches12,
|
||||
notches20,
|
||||
}
|
||||
|
||||
enum sound-category {
|
||||
master,
|
||||
music,
|
||||
records,
|
||||
weather,
|
||||
blocks,
|
||||
hostile,
|
||||
neutral,
|
||||
players,
|
||||
ambient,
|
||||
voice,
|
||||
ui,
|
||||
}
|
||||
|
||||
enum entity-anchor {
|
||||
feet,
|
||||
eyes,
|
||||
}
|
||||
|
||||
variant number {
|
||||
float64(f64),
|
||||
float32(f32),
|
||||
int32(s32),
|
||||
int64(s64),
|
||||
}
|
||||
|
||||
variant not-in-bounds {
|
||||
lower-bound(tuple<number, number>),
|
||||
upper-bound(tuple<number, number>),
|
||||
}
|
||||
|
||||
variant arg {
|
||||
entities(list<entity>),
|
||||
entity(entity),
|
||||
players(list<player>),
|
||||
block-pos(block-position),
|
||||
pos3d(position),
|
||||
pos2d(tuple<f64, f64>),
|
||||
rotation(tuple<f32, bool, f32, bool>),
|
||||
game-mode(gamemode),
|
||||
difficulty(difficulty),
|
||||
item(string),
|
||||
item-predicate(string),
|
||||
resource-location(string),
|
||||
block(string),
|
||||
block-predicate(string),
|
||||
bossbar-color(bossbar-color),
|
||||
bossbar-style(bossbar-style),
|
||||
particle(string),
|
||||
msg(string),
|
||||
text-component(text-component),
|
||||
time(s32),
|
||||
num(result<number, not-in-bounds>),
|
||||
%bool(bool),
|
||||
simple(string),
|
||||
sound-category(sound-category),
|
||||
damage-type(string),
|
||||
effect(string),
|
||||
enchantment(string),
|
||||
entity-anchor(entity-anchor),
|
||||
}
|
||||
|
||||
resource consumed-args {
|
||||
get-value: func(key: string) -> arg;
|
||||
}
|
||||
|
||||
variant command-sender-type {
|
||||
rcon,
|
||||
console,
|
||||
player(player),
|
||||
command-block(tuple<command-block-entity, %world>),
|
||||
dummy,
|
||||
}
|
||||
|
||||
enum permission-level {
|
||||
zero,
|
||||
one,
|
||||
two,
|
||||
three,
|
||||
four,
|
||||
}
|
||||
|
||||
resource command-sender {
|
||||
get-command-sender-type: func() -> command-sender-type;
|
||||
send-message: func(text: text-component);
|
||||
set-success-count: func(count: s32);
|
||||
is-player: func() -> bool;
|
||||
is-console: func() -> bool;
|
||||
as-player: func() -> option<player>;
|
||||
permission-level: func() -> permission-level;
|
||||
has-permission-level: func(level: permission-level) -> bool;
|
||||
has-permission: func(server: borrow<server>, node: string) -> bool;
|
||||
position: func() -> option<position>;
|
||||
%world: func() -> option<%world>;
|
||||
get-locale: func() -> locale;
|
||||
should-receive-feedback: func() -> bool;
|
||||
should-broadcast-console-to-ops: func() -> bool;
|
||||
should-track-output: func() -> bool;
|
||||
}
|
||||
|
||||
enum string-type {
|
||||
single-word,
|
||||
quotable,
|
||||
greedy,
|
||||
}
|
||||
|
||||
variant argument-type {
|
||||
%bool,
|
||||
float(tuple<option<f32>, option<f32>>),
|
||||
double(tuple<option<f64>, option<f64>>),
|
||||
integer(tuple<option<s32>, option<s32>>),
|
||||
long(tuple<option<s64>, option<s64>>),
|
||||
%string(string-type),
|
||||
entities,
|
||||
entity,
|
||||
%players,
|
||||
game-profile,
|
||||
block-pos,
|
||||
position3d,
|
||||
position2d,
|
||||
block-state,
|
||||
block-predicate,
|
||||
item,
|
||||
item-predicate,
|
||||
component,
|
||||
rotation,
|
||||
%resource-location,
|
||||
entity-anchor,
|
||||
gamemode,
|
||||
difficulty,
|
||||
time(s32),
|
||||
%resource(string),
|
||||
}
|
||||
|
||||
variant command-error {
|
||||
invalid-consumption(option<string>),
|
||||
invalid-requirement,
|
||||
permission-denied,
|
||||
command-failed(text-component),
|
||||
}
|
||||
|
||||
resource command-node {
|
||||
literal: static func(name: string) -> command-node;
|
||||
argument: static func(name: string, arg-type: argument-type) -> command-node;
|
||||
then: func(node: command-node);
|
||||
execute-with-handler-id: func(handler-id: u32);
|
||||
require-with-handler-id: func(handler-id: u32);
|
||||
}
|
||||
|
||||
resource command {
|
||||
/// First name is primary, rest are aliases
|
||||
constructor(names: list<string>, description: string);
|
||||
then: func(node: command-node);
|
||||
execute-with-handler-id: func(handler-id: u32);
|
||||
}
|
||||
}
|
||||
201
src/pumpkin_api/wit_files/common.wit
Normal file
201
src/pumpkin_api/wit_files/common.wit
Normal file
@ -0,0 +1,201 @@
|
||||
/// Provides common types and utilities used across the entire plugin API.
|
||||
interface common {
|
||||
/// Serialized text component as a postcard byte array.
|
||||
/// @deprecated Use the text-component resource from the text interface instead.
|
||||
type raw-text-component = list<u8>;
|
||||
|
||||
/// A position in the world grid (integers).
|
||||
type block-position = tuple<s32, s32, s32>;
|
||||
|
||||
/// A precise coordinate in the world (floats).
|
||||
type position = tuple<f64, f64, f64>;
|
||||
|
||||
/// Represents the hands of a player.
|
||||
enum hand {
|
||||
left,
|
||||
right,
|
||||
}
|
||||
|
||||
/// Represents the game modes available in Minecraft.
|
||||
enum game-mode {
|
||||
survival,
|
||||
creative,
|
||||
adventure,
|
||||
spectator,
|
||||
}
|
||||
|
||||
/// The 16 base Minecraft colors.
|
||||
enum named-color {
|
||||
black,
|
||||
dark-blue,
|
||||
dark-green,
|
||||
dark-aqua,
|
||||
dark-red,
|
||||
dark-purple,
|
||||
gold,
|
||||
gray,
|
||||
dark-gray,
|
||||
blue,
|
||||
green,
|
||||
aqua,
|
||||
red,
|
||||
light-purple,
|
||||
yellow,
|
||||
white,
|
||||
}
|
||||
|
||||
/// An RGB color represented by its red, green, and blue components.
|
||||
record rgb-color {
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
/// An ARGB color with alpha (transparency) channel.
|
||||
record argb-color {
|
||||
a: u8,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
/// Represents a stack of items with its type and count.
|
||||
record item-stack {
|
||||
/// The unique registry key (e.g., "minecraft:diamond").
|
||||
registry-key: string,
|
||||
/// The number of items in the stack.
|
||||
count: u8,
|
||||
}
|
||||
|
||||
/// All Minecraft-supported locales.
|
||||
enum locale {
|
||||
af-za,
|
||||
ar-sa,
|
||||
ast-es,
|
||||
az-az,
|
||||
ba-ru,
|
||||
bar,
|
||||
be-by,
|
||||
bg-bg,
|
||||
br-fr,
|
||||
brb,
|
||||
bs-ba,
|
||||
ca-es,
|
||||
cs-cz,
|
||||
cy-gb,
|
||||
da-dk,
|
||||
de-at,
|
||||
de-ch,
|
||||
de-de,
|
||||
el-gr,
|
||||
en-au,
|
||||
en-ca,
|
||||
en-gb,
|
||||
en-nz,
|
||||
en-pt,
|
||||
en-ud,
|
||||
en-us,
|
||||
enp,
|
||||
enws,
|
||||
eo-uy,
|
||||
es-ar,
|
||||
es-cl,
|
||||
es-ec,
|
||||
es-es,
|
||||
es-mx,
|
||||
es-uy,
|
||||
es-ve,
|
||||
esan,
|
||||
et-ee,
|
||||
eu-es,
|
||||
fa-ir,
|
||||
fi-fi,
|
||||
fil-ph,
|
||||
fo-fo,
|
||||
fr-ca,
|
||||
fr-fr,
|
||||
fra-de,
|
||||
fur-it,
|
||||
fy-nl,
|
||||
ga-ie,
|
||||
gd-gb,
|
||||
gl-es,
|
||||
haw-us,
|
||||
he-il,
|
||||
hi-in,
|
||||
hr-hr,
|
||||
hu-hu,
|
||||
hy-am,
|
||||
id-id,
|
||||
ig-ng,
|
||||
io-en,
|
||||
is-is,
|
||||
isv,
|
||||
it-it,
|
||||
ja-jp,
|
||||
jbo-en,
|
||||
ka-ge,
|
||||
kk-kz,
|
||||
kn-in,
|
||||
ko-kr,
|
||||
ksh,
|
||||
kw-gb,
|
||||
la-la,
|
||||
lb-lu,
|
||||
li-li,
|
||||
lmo,
|
||||
lo-la,
|
||||
lol-us,
|
||||
lt-lt,
|
||||
lv-lv,
|
||||
lzh,
|
||||
mk-mk,
|
||||
mn-mn,
|
||||
ms-my,
|
||||
mt-mt,
|
||||
nah,
|
||||
nds-de,
|
||||
nl-be,
|
||||
nl-nl,
|
||||
nn-no,
|
||||
no-no,
|
||||
oc-fr,
|
||||
ovd,
|
||||
pl-pl,
|
||||
pt-br,
|
||||
pt-pt,
|
||||
qya-aa,
|
||||
ro-ro,
|
||||
rpr,
|
||||
ru-ru,
|
||||
ry-ua,
|
||||
sah-sah,
|
||||
se-no,
|
||||
sk-sk,
|
||||
sl-si,
|
||||
so-so,
|
||||
sq-al,
|
||||
sr-cs,
|
||||
sr-sp,
|
||||
sv-se,
|
||||
sxu,
|
||||
szl,
|
||||
ta-in,
|
||||
th-th,
|
||||
tl-ph,
|
||||
tlh-aa,
|
||||
tok,
|
||||
tr-tr,
|
||||
tt-ru,
|
||||
uk-ua,
|
||||
val-es,
|
||||
vec-it,
|
||||
vi-vn,
|
||||
yi-de,
|
||||
yo-ng,
|
||||
zh-cn,
|
||||
zh-hk,
|
||||
zh-tw,
|
||||
zlm-arab,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,529 @@
|
||||
import asyncio
|
||||
import componentize_py_runtime
|
||||
import subprocess
|
||||
|
||||
from os import PathLike
|
||||
from socket import AddressFamily, AddressInfo, SocketKind, socket
|
||||
from concurrent.futures import Executor
|
||||
from componentize_py_types import Result, Ok, Err
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional, TypeVar, TypeVarTuple, Callable, IO, Literal, cast
|
||||
from contextvars import ContextVar, Context
|
||||
from collections.abc import Coroutine, Awaitable, Sequence
|
||||
from asyncio.protocols import BaseProtocol
|
||||
from asyncio.transports import Transport, WriteTransport, DatagramTransport, SubprocessTransport, ReadTransport
|
||||
from asyncio.base_events import Server
|
||||
|
||||
try:
|
||||
from ssl import SSLContext
|
||||
except:
|
||||
pass
|
||||
|
||||
@dataclass
|
||||
class _FutureState:
|
||||
waitable_set: int | None
|
||||
futures: dict[int, Any]
|
||||
handles: list[asyncio.Handle]
|
||||
pending_count: int
|
||||
|
||||
class _ReturnCode:
|
||||
COMPLETED = 0
|
||||
DROPPED = 1
|
||||
CANCELLED = 2
|
||||
|
||||
class _CallbackCode:
|
||||
EXIT = 0
|
||||
YIELD = 1
|
||||
WAIT = 2
|
||||
POLL = 3
|
||||
|
||||
class _Event:
|
||||
NONE = 0
|
||||
SUBTASK = 1
|
||||
STREAM_READ = 2
|
||||
STREAM_WRITE = 3
|
||||
FUTURE_READ = 4
|
||||
FUTURE_WRITE = 5
|
||||
CANCELLED = 6
|
||||
|
||||
class _Status:
|
||||
STARTING = 0
|
||||
STARTED = 1
|
||||
RETURNED = 2
|
||||
START_CANCELLED = 3
|
||||
RETURN_CANCELLED = 4
|
||||
|
||||
_T = TypeVar("_T")
|
||||
_Ts = TypeVarTuple("_Ts")
|
||||
_ProtocolT = TypeVar("_ProtocolT", bound=BaseProtocol)
|
||||
|
||||
async def _noop() -> None:
|
||||
pass
|
||||
|
||||
class _Loop(asyncio.AbstractEventLoop):
|
||||
def __init__(self) -> None:
|
||||
self.running: bool = False
|
||||
self.exception: Optional[Any] = None
|
||||
|
||||
def poll(self, future_state: _FutureState) -> None:
|
||||
while True:
|
||||
handles = future_state.handles
|
||||
future_state.handles = []
|
||||
for handle in handles:
|
||||
if not handle._cancelled:
|
||||
handle._run()
|
||||
|
||||
if self.exception is not None:
|
||||
raise self.exception
|
||||
|
||||
if len(handles) == 0 and len(future_state.handles) == 0:
|
||||
return
|
||||
|
||||
def get_debug(self) -> bool:
|
||||
return False
|
||||
|
||||
def is_running(self) -> bool:
|
||||
return self.running
|
||||
|
||||
def is_closed(self) -> bool:
|
||||
return not self.running
|
||||
|
||||
def stop(self) -> None:
|
||||
self.running = False
|
||||
|
||||
def close(self) -> None:
|
||||
self.running = False
|
||||
|
||||
def shutdown_asyncgens(self) -> Coroutine[Any, Any, None]:
|
||||
return _noop()
|
||||
|
||||
def call_exception_handler(self, context: dict[str, Any]) -> None:
|
||||
self.exception = context.get('exception', None)
|
||||
|
||||
def call_soon(self,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.Handle:
|
||||
global _future_state
|
||||
|
||||
if context is not None:
|
||||
future_state = context[_future_state]
|
||||
handle = asyncio.Handle(callback, args, self, context)
|
||||
future_state.handles.append(handle)
|
||||
return handle
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def create_task(self, coroutine: Coroutine[Any, Any, _T], name: str | None = None, context: Context | None = None) -> asyncio.Task[_T]:
|
||||
return asyncio.Task(coroutine, loop=self, context=context)
|
||||
|
||||
def create_future(self) -> asyncio.Future[Any]:
|
||||
return asyncio.Future(loop=self)
|
||||
|
||||
# The remaining methods should be irrelevant for our purposes and thus unimplemented
|
||||
|
||||
def run_until_complete(self, future: Awaitable[_T]) -> _T:
|
||||
raise NotImplementedError
|
||||
|
||||
def run_forever(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def shutdown_default_executor(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def call_later(self,
|
||||
delay: float,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.TimerHandle:
|
||||
raise NotImplementedError
|
||||
|
||||
def call_at(self,
|
||||
when: float,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.TimerHandle:
|
||||
raise NotImplementedError
|
||||
|
||||
def time(self) -> float:
|
||||
raise NotImplementedError
|
||||
|
||||
def call_soon_threadsafe(self,
|
||||
callback: Callable[[*_Ts], object],
|
||||
*args: *_Ts,
|
||||
context: Context | None = None) -> asyncio.Handle:
|
||||
raise NotImplementedError
|
||||
|
||||
def run_in_executor(self,
|
||||
executor: Executor | None,
|
||||
func: Callable[[*_Ts], _T],
|
||||
*args: *_Ts) -> asyncio.Future[_T]:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_default_executor(self, executor: Executor) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def getaddrinfo(
|
||||
self,
|
||||
host: bytes | str | None,
|
||||
port: bytes | str | int | None,
|
||||
*,
|
||||
family: int = 0,
|
||||
type: int = 0,
|
||||
proto: int = 0,
|
||||
flags: int = 0,
|
||||
) -> list[tuple[AddressFamily, SocketKind, int, str, tuple[str, int] | tuple[str, int, int, int]]]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def getnameinfo(self,
|
||||
sockaddr: tuple[str, int] | tuple[str, int, int, int],
|
||||
flags: int = 0) -> tuple[str, str]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_connection(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
host: str | None = ...,
|
||||
port: int | None = ...,
|
||||
*,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
family: int = 0,
|
||||
proto: int = 0,
|
||||
flags: int = 0,
|
||||
sock: socket | None = None,
|
||||
local_addr: tuple[str, int] | None = None,
|
||||
server_hostname: str | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
happy_eyeballs_delay: float | None = None,
|
||||
interleave: int | None = None,
|
||||
) -> tuple[Transport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_server(
|
||||
self,
|
||||
protocol_factory: Callable[[], BaseProtocol],
|
||||
host: str | Sequence[str] | None = None,
|
||||
port: int | None = None,
|
||||
*,
|
||||
family: int = AddressFamily.AF_UNSPEC,
|
||||
flags: int = AddressInfo.AI_PASSIVE,
|
||||
sock: socket | None = ...,
|
||||
backlog: int = 100,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
reuse_address: bool | None = None,
|
||||
reuse_port: bool | None = None,
|
||||
keep_alive: bool | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
start_serving: bool = True,
|
||||
) -> Server:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sendfile(self,
|
||||
transport: WriteTransport,
|
||||
file: IO[bytes],
|
||||
offset: int = 0,
|
||||
count: int | None = None,
|
||||
*,
|
||||
fallback: bool = True
|
||||
) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
async def start_tls(
|
||||
self,
|
||||
transport: WriteTransport,
|
||||
protocol: BaseProtocol,
|
||||
sslcontext: SSLContext,
|
||||
*,
|
||||
server_side: bool = False,
|
||||
server_hostname: str | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
) -> Transport | None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_connection(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
path: str | None = None,
|
||||
*,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
sock: socket | None = None,
|
||||
server_hostname: str | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
) -> tuple[Transport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_server(
|
||||
self,
|
||||
protocol_factory: Callable[[], BaseProtocol],
|
||||
path: str | PathLike[str] | None = None,
|
||||
*,
|
||||
sock: socket | None = None,
|
||||
backlog: int = 100,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
start_serving: bool = True,
|
||||
) -> Server:
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_accepted_socket(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
sock: socket,
|
||||
*,
|
||||
ssl: bool | SSLContext | None = None,
|
||||
ssl_handshake_timeout: float | None = None,
|
||||
ssl_shutdown_timeout: float | None = None,
|
||||
) -> tuple[Transport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_datagram_endpoint(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
local_addr: tuple[str, int] | str | None = None,
|
||||
remote_addr: tuple[str, int] | str | None = None,
|
||||
*,
|
||||
family: int = 0,
|
||||
proto: int = 0,
|
||||
flags: int = 0,
|
||||
reuse_address: bool | None = None,
|
||||
reuse_port: bool | None = None,
|
||||
allow_broadcast: bool | None = None,
|
||||
sock: socket | None = None,
|
||||
) -> tuple[DatagramTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_read_pipe(self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
pipe: Any) -> tuple[ReadTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_write_pipe(self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
pipe: Any) -> tuple[WriteTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_shell(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
cmd: bytes | str,
|
||||
*,
|
||||
stdin: int | IO[Any] | None = -1,
|
||||
stdout: int | IO[Any] | None = -1,
|
||||
stderr: int | IO[Any] | None = -1,
|
||||
universal_newlines: Literal[False] = False,
|
||||
shell: Literal[True] = True,
|
||||
bufsize: Literal[0] = 0,
|
||||
encoding: None = None,
|
||||
errors: None = None,
|
||||
text: Literal[False] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> tuple[SubprocessTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_exec(
|
||||
self,
|
||||
protocol_factory: Callable[[], _ProtocolT],
|
||||
program: Any,
|
||||
*args: Any,
|
||||
stdin: int | IO[Any] | None = -1,
|
||||
stdout: int | IO[Any] | None = -1,
|
||||
stderr: int | IO[Any] | None = -1,
|
||||
universal_newlines: Literal[False] = False,
|
||||
shell: Literal[False] = False,
|
||||
bufsize: Literal[0] = 0,
|
||||
encoding: None = None,
|
||||
errors: None = None,
|
||||
**kwargs: Any,
|
||||
) -> tuple[SubprocessTransport, _ProtocolT]:
|
||||
raise NotImplementedError
|
||||
|
||||
def add_reader(self, fd: Any, callback: Callable[[*_Ts], Any], *args: *_Ts) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_reader(self, fd: Any) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def add_writer(self, fd: Any, callback: Callable[[*_Ts], Any], *args: *_Ts) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_writer(self, fd: Any) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv(self, sock: socket, nbytes: int) -> bytes:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv_into(self, sock: socket, buf: Any) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom(self, sock: socket, bufsize: int) -> tuple[bytes, Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom_into(self, sock: socket, buf: Any, nbytes: int = 0) -> tuple[int, Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendall(self, sock: socket, data: Any) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendto(self, sock: socket, data: Any, address: Any) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_connect(self, sock: socket, address: Any) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_accept(self, sock: socket) -> tuple[socket, Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendfile(
|
||||
self,
|
||||
sock: socket,
|
||||
file: IO[bytes],
|
||||
offset: int = 0,
|
||||
count: int | None = None,
|
||||
*,
|
||||
fallback: bool | None = None
|
||||
) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
def add_signal_handler(self, sig: int, callback: Callable[[*_Ts], object], *args: *_Ts) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_signal_handler(self, sig: int) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_task_factory(self, factory: Any | None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_task_factory(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_exception_handler(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_exception_handler(self, handler: Any | None) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def default_exception_handler(self, context: dict[str, Any]) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_debug(self, enabled: bool) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
_future_state: ContextVar[_FutureState] = ContextVar("_future_state")
|
||||
_loop = _Loop()
|
||||
asyncio.set_event_loop(_loop)
|
||||
_loop.running = True
|
||||
asyncio.events._set_running_loop(_loop)
|
||||
|
||||
def _set_future_state(future_state: _FutureState) -> None:
|
||||
global _future_state
|
||||
|
||||
_future_state.set(future_state)
|
||||
|
||||
async def _return_result(export_index: int, borrows: int, coroutine: Any) -> None:
|
||||
global _future_state
|
||||
|
||||
try:
|
||||
try:
|
||||
result: Result[Any, Any] = Ok(await coroutine)
|
||||
except Err as e:
|
||||
result = e
|
||||
|
||||
componentize_py_runtime.call_task_return(export_index, borrows, result)
|
||||
except Exception as e:
|
||||
_loop.exception = e
|
||||
|
||||
assert _future_state.get().pending_count > 0
|
||||
_future_state.get().pending_count -= 1
|
||||
|
||||
def first_poll(export_index: int, borrows: int, coroutine: Any) -> int:
|
||||
context = Context()
|
||||
future_state = _FutureState(None, {}, [], 1)
|
||||
context.run(_set_future_state, future_state)
|
||||
asyncio.create_task(_return_result(export_index, borrows, coroutine), context=context)
|
||||
return _poll(future_state)
|
||||
|
||||
def _poll(future_state: _FutureState) -> int:
|
||||
global _loop
|
||||
|
||||
_loop.poll(future_state)
|
||||
|
||||
if future_state.pending_count == 0:
|
||||
if future_state.waitable_set is not None:
|
||||
componentize_py_runtime.waitable_set_drop(future_state.waitable_set)
|
||||
|
||||
return _CallbackCode.EXIT
|
||||
else:
|
||||
waitable_set = future_state.waitable_set
|
||||
assert waitable_set is not None
|
||||
componentize_py_runtime.context_set(future_state)
|
||||
return _CallbackCode.WAIT | (waitable_set << 4)
|
||||
|
||||
def callback(event0: int, event1: int, event2: int) -> int:
|
||||
future_state = componentize_py_runtime.context_get()
|
||||
componentize_py_runtime.context_set(None)
|
||||
|
||||
match event0:
|
||||
case _Event.NONE:
|
||||
pass
|
||||
case _Event.SUBTASK:
|
||||
match event2:
|
||||
case _Status.STARTING:
|
||||
raise AssertionError
|
||||
case _Status.STARTED:
|
||||
pass
|
||||
case _Status.RETURNED:
|
||||
componentize_py_runtime.waitable_join(event1, 0)
|
||||
componentize_py_runtime.subtask_drop(event1)
|
||||
future_state.futures.pop(event1).set_result(event2)
|
||||
case _:
|
||||
# todo
|
||||
raise NotImplementedError
|
||||
case _Event.STREAM_READ | _Event.STREAM_WRITE | _Event.FUTURE_READ | _Event.FUTURE_WRITE:
|
||||
componentize_py_runtime.waitable_join(event1, 0)
|
||||
future_state.futures.pop(event1).set_result(event2)
|
||||
case _:
|
||||
# todo
|
||||
raise NotImplementedError
|
||||
|
||||
return _poll(future_state)
|
||||
|
||||
async def await_result[T](result: Result[T, tuple[int, int]]) -> T:
|
||||
global _loop
|
||||
global _future_state
|
||||
|
||||
if isinstance(result, Ok):
|
||||
return result.value
|
||||
else:
|
||||
future_state = _future_state.get()
|
||||
waitable, promise = result.value
|
||||
future = _loop.create_future()
|
||||
future_state.futures[waitable] = future
|
||||
|
||||
if future_state.waitable_set is None:
|
||||
future_state.waitable_set = componentize_py_runtime.waitable_set_new()
|
||||
componentize_py_runtime.waitable_join(waitable, future_state.waitable_set)
|
||||
|
||||
return cast(T, componentize_py_runtime.promise_get_result(await future, promise))
|
||||
|
||||
async def _wrap_spawned(coroutine: Any) -> None:
|
||||
global _future_state
|
||||
|
||||
try:
|
||||
await coroutine
|
||||
except Exception as e:
|
||||
_loop.exception = e
|
||||
|
||||
assert _future_state.get().pending_count > 0
|
||||
_future_state.get().pending_count -= 1
|
||||
|
||||
def spawn(coroutine: Any) -> None:
|
||||
global _future_state
|
||||
|
||||
_future_state.get().pending_count += 1
|
||||
|
||||
asyncio.create_task(_wrap_spawned(coroutine))
|
||||
@ -0,0 +1,93 @@
|
||||
import componentize_py_runtime
|
||||
import componentize_py_async_support
|
||||
import weakref
|
||||
|
||||
from typing import TypeVar, Generic, cast, Self, Any, Callable
|
||||
from types import TracebackType
|
||||
from componentize_py_async_support import _ReturnCode
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class FutureReader(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.future_drop_readable, type_, handle)
|
||||
|
||||
async def read(self) -> T:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
result = await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.future_read(self.type_, handle)
|
||||
)
|
||||
componentize_py_runtime.future_drop_readable(self.type_, handle)
|
||||
return cast(T, result)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
if self.handle is not None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
componentize_py_runtime.future_drop_readable(self.type_, handle)
|
||||
|
||||
return None
|
||||
|
||||
async def write(type_: int, handle: int, value: Any) -> None:
|
||||
await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.future_write(type_, handle, value)
|
||||
)
|
||||
componentize_py_runtime.future_drop_writable(type_, handle)
|
||||
|
||||
def write_default(type_: int, handle: int, default: Callable[[], Any]) -> None:
|
||||
componentize_py_async_support.spawn(write(type_, handle, default()))
|
||||
|
||||
class FutureWriter(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int, default: Callable[[], T]):
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.default = default
|
||||
self.finalizer = weakref.finalize(self, write_default, type_, handle, default)
|
||||
|
||||
async def write(self, value: T) -> bool:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
code, _ = await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.future_write(self.type_, handle, value)
|
||||
)
|
||||
componentize_py_runtime.future_drop_writable(self.type_, handle)
|
||||
match code:
|
||||
case _ReturnCode.COMPLETED:
|
||||
return True
|
||||
case _ReturnCode.DROPPED:
|
||||
return False
|
||||
case _ReturnCode.CANCELLED:
|
||||
# todo
|
||||
raise NotImplementedError
|
||||
case _:
|
||||
raise AssertionError
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
if self.handle is not None:
|
||||
componentize_py_async_support.spawn(self.write(self.default()))
|
||||
|
||||
return None
|
||||
@ -0,0 +1,189 @@
|
||||
import componentize_py_runtime
|
||||
import componentize_py_async_support
|
||||
import weakref
|
||||
|
||||
from typing import TypeVar, Generic, Self, cast
|
||||
from types import TracebackType
|
||||
from componentize_py_async_support import _ReturnCode
|
||||
|
||||
class ByteStreamReader:
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.writer_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_readable, type_, handle)
|
||||
|
||||
async def read(self, max_count: int) -> bytes:
|
||||
if self.writer_dropped:
|
||||
return bytes()
|
||||
|
||||
code, values = await self._read(max_count)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.writer_dropped = True
|
||||
|
||||
return values
|
||||
|
||||
async def _read(self, max_count: int) -> tuple[int, bytes]:
|
||||
if self.handle is not None:
|
||||
return cast(tuple[int, bytes], await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_read(self.type_, self.handle, max_count)
|
||||
))
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_readable(self.type_, handle)
|
||||
return None
|
||||
|
||||
class ByteStreamWriter:
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.reader_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_writable, type_, handle)
|
||||
|
||||
async def write(self, source: bytes) -> int:
|
||||
if self.reader_dropped:
|
||||
return 0
|
||||
|
||||
code, count = await self._write(source)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.reader_dropped = True
|
||||
|
||||
return count
|
||||
|
||||
async def _write(self, source: bytes) -> tuple[int, int]:
|
||||
if self.handle is not None:
|
||||
return await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_write(self.type_, self.handle, source)
|
||||
)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
async def write_all(self, source: bytes) -> int:
|
||||
total = 0
|
||||
|
||||
while len(source) > 0 and not self.reader_dropped:
|
||||
count = await self.write(source)
|
||||
source = source[count:]
|
||||
total += count
|
||||
|
||||
return total
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_writable(self.type_, handle)
|
||||
return None
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
class StreamReader(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.writer_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_readable, type_, handle)
|
||||
|
||||
async def read(self, max_count: int) -> list[T]:
|
||||
if self.writer_dropped:
|
||||
return []
|
||||
|
||||
code, values = await self._read(max_count)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.writer_dropped = True
|
||||
|
||||
return values
|
||||
|
||||
async def _read(self, max_count: int) -> tuple[int, list[T]]:
|
||||
if self.handle is not None:
|
||||
return cast(tuple[int, list[T]], await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_read(self.type_, self.handle, max_count)
|
||||
))
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_readable(self.type_, handle)
|
||||
return None
|
||||
|
||||
class StreamWriter(Generic[T]):
|
||||
def __init__(self, type_: int, handle: int):
|
||||
self.reader_dropped = False
|
||||
self.type_ = type_
|
||||
self.handle: int | None = handle
|
||||
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_writable, type_, handle)
|
||||
|
||||
async def write(self, source: list[T]) -> int:
|
||||
if self.reader_dropped:
|
||||
return 0
|
||||
|
||||
code, count = await self._write(source)
|
||||
|
||||
if code == _ReturnCode.DROPPED:
|
||||
self.reader_dropped = True
|
||||
|
||||
return count
|
||||
|
||||
async def _write(self, source: list[T]) -> tuple[int, int]:
|
||||
if self.handle is not None:
|
||||
return await componentize_py_async_support.await_result(
|
||||
componentize_py_runtime.stream_write(self.type_, self.handle, source)
|
||||
)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
async def write_all(self, source: list[T]) -> int:
|
||||
total = 0
|
||||
|
||||
while len(source) > 0 and not self.reader_dropped:
|
||||
count = await self.write(source)
|
||||
source = source[count:]
|
||||
total += count
|
||||
|
||||
return total
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
def __exit__(self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_value: BaseException | None,
|
||||
traceback: TracebackType | None) -> bool | None:
|
||||
self.finalizer.detach()
|
||||
handle = self.handle
|
||||
self.handle = None
|
||||
if handle is not None:
|
||||
componentize_py_runtime.stream_drop_writable(self.type_, handle)
|
||||
return None
|
||||
34
src/pumpkin_api/wit_files/componentize_py_runtime.pyi
Normal file
34
src/pumpkin_api/wit_files/componentize_py_runtime.pyi
Normal file
@ -0,0 +1,34 @@
|
||||
from typing import Any
|
||||
from componentize_py_types import Result
|
||||
|
||||
def call_task_return(index: int, borrows: int, result: Any) -> None: ...
|
||||
|
||||
def waitable_set_drop(set: int) -> None: ...
|
||||
|
||||
def context_set(value: Any) -> None: ...
|
||||
|
||||
def context_get() -> Any: ...
|
||||
|
||||
def waitable_join(waitable: int, set: int) -> None: ...
|
||||
|
||||
def subtask_drop(task: int) -> None: ...
|
||||
|
||||
def waitable_set_new() -> int: ...
|
||||
|
||||
def promise_get_result(event: int, promise: int) -> Any: ...
|
||||
|
||||
def future_read(ty: int, future: int) -> Result[Any, tuple[int, int]]: ...
|
||||
|
||||
def future_write(ty: int, future: int, value: Any) -> Result[tuple[int, int], tuple[int, int]]: ...
|
||||
|
||||
def future_drop_readable(ty: int, future: int) -> None: ...
|
||||
|
||||
def future_drop_writable(ty: int, future: int) -> None: ...
|
||||
|
||||
def stream_read(ty: int, stream: int, max_count: int) -> Result[tuple[int, bytes | list[Any]], tuple[int, int]]: ...
|
||||
|
||||
def stream_write(ty: int, stream: int, values: bytes | list[Any]) -> Result[tuple[int, int], tuple[int, int]]: ...
|
||||
|
||||
def stream_drop_readable(ty: int, stream: int) -> None: ...
|
||||
|
||||
def stream_drop_writable(ty: int, stream: int) -> None: ...
|
||||
19
src/pumpkin_api/wit_files/componentize_py_types.py
Normal file
19
src/pumpkin_api/wit_files/componentize_py_types.py
Normal file
@ -0,0 +1,19 @@
|
||||
from typing import TypeVar, Generic, Union
|
||||
from dataclasses import dataclass
|
||||
|
||||
S = TypeVar('S')
|
||||
@dataclass
|
||||
class Some(Generic[S]):
|
||||
value: S
|
||||
|
||||
T = TypeVar('T')
|
||||
@dataclass
|
||||
class Ok(Generic[T]):
|
||||
value: T
|
||||
|
||||
E = TypeVar('E')
|
||||
@dataclass(frozen=True)
|
||||
class Err(Generic[E], Exception):
|
||||
value: E
|
||||
|
||||
Result = Union[Ok[T], Err[E]]
|
||||
33
src/pumpkin_api/wit_files/context.wit
Normal file
33
src/pumpkin_api/wit_files/context.wit
Normal file
@ -0,0 +1,33 @@
|
||||
/// The core context provided to a plugin during initialization and event handling.
|
||||
interface context {
|
||||
use server.{server};
|
||||
use event.{event-type, event-priority};
|
||||
use command.{command};
|
||||
use permission.{permission};
|
||||
|
||||
/// A contextual handle for plugin-related operations.
|
||||
resource context {
|
||||
/// Registers a handler for a specific event.
|
||||
///
|
||||
/// * `handler-id`: Unique ID for the event handler.
|
||||
/// * `event-type`: The type of event to listen for.
|
||||
/// * `event-priority`: When this handler should be called relative to others.
|
||||
/// * `blocking`: Whether the event should wait for this handler to finish.
|
||||
register-event: func(handler-id: u32, event-type: event-type, event-priority: event-priority, blocking: bool);
|
||||
|
||||
/// Registers a new command.
|
||||
///
|
||||
/// * `command`: The command definition.
|
||||
/// * `permission`: The required permission node to execute this command.
|
||||
register-command: func(command: command, permission: string);
|
||||
|
||||
/// Registers a permission node with the server.
|
||||
register-permission: func(permission: permission) -> result<_, string>;
|
||||
|
||||
/// Returns the path to the plugin's private data folder.
|
||||
get-data-folder: func() -> string;
|
||||
|
||||
/// Returns the global server instance.
|
||||
get-server: func() -> server;
|
||||
}
|
||||
}
|
||||
36
src/pumpkin_api/wit_files/entity.wit
Normal file
36
src/pumpkin_api/wit_files/entity.wit
Normal file
@ -0,0 +1,36 @@
|
||||
interface entity {
|
||||
use common.{block-position};
|
||||
|
||||
resource block-entity {
|
||||
resource-location: func() -> string;
|
||||
get-position: func() -> block-position;
|
||||
get-id: func() -> u32;
|
||||
// write-nbt: func(nbt: nbt-compound);
|
||||
// from-nbt: func(nbt: nbt-compound, position: block-position) -> entity;
|
||||
// tick: func(world: simple-world);
|
||||
// write-internal: func(nbt: nbt-compound);
|
||||
// chunk-data-nbt: func() -> option<nbt-compound;
|
||||
// get-inventory: func() -> option<inventory>;
|
||||
// set-block-state: func(block-state: block-state-id);
|
||||
// on-block-replaced: func(world: simple-world, position: block-position);
|
||||
is-dirty: func() -> bool;
|
||||
clear-dirty: func();
|
||||
// to-property-delegate: func() -> option<property-delegate>;
|
||||
// to-experience-container: func() -> option<experience-container>;
|
||||
}
|
||||
|
||||
resource command-block-entity {
|
||||
get-block-entity: func () -> block-entity;
|
||||
last-output: func() -> string;
|
||||
track-output: func() -> bool;
|
||||
success-count: func() -> u32;
|
||||
command: func() -> string;
|
||||
auto: func() -> bool;
|
||||
condition-met: func() -> bool;
|
||||
powered: func() -> bool;
|
||||
}
|
||||
|
||||
variant entity {
|
||||
command-block-entity(command-block-entity),
|
||||
}
|
||||
}
|
||||
311
src/pumpkin_api/wit_files/event.wit
Normal file
311
src/pumpkin_api/wit_files/event.wit
Normal file
@ -0,0 +1,311 @@
|
||||
interface event {
|
||||
use common.{block-position, game-mode, hand, item-stack, position};
|
||||
use player.{player};
|
||||
use text.{text-component};
|
||||
use %world.{%world};
|
||||
|
||||
enum event-priority {
|
||||
highest,
|
||||
high,
|
||||
normal,
|
||||
low,
|
||||
lowest,
|
||||
}
|
||||
|
||||
record player-join-event-data {
|
||||
player: player,
|
||||
join-message: text-component,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-leave-event-data {
|
||||
player: player,
|
||||
leave-message: text-component,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-login-event-data {
|
||||
player: player,
|
||||
kick-message: text-component,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-chat-event-data {
|
||||
player: player,
|
||||
message: string,
|
||||
recipients: list<player>,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-command-send-event-data {
|
||||
player: player,
|
||||
command: string,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-permission-check-event-data {
|
||||
player: player,
|
||||
permission: string,
|
||||
permission-result: bool
|
||||
}
|
||||
|
||||
record player-move-event-data {
|
||||
player: player,
|
||||
from-position: position,
|
||||
to-position: position,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-teleport-event-data {
|
||||
player: player,
|
||||
from-position: position,
|
||||
to-position: position,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-change-world-event-data {
|
||||
player: player,
|
||||
previous-world: %world,
|
||||
new-world: %world,
|
||||
position: position,
|
||||
yaw: f32,
|
||||
pitch: f32,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-exp-change-event-data {
|
||||
player: player,
|
||||
amount: s32
|
||||
}
|
||||
|
||||
record player-item-held-event-data {
|
||||
player: player,
|
||||
previous-slot: u8,
|
||||
new-slot: u8,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-changed-main-hand-event-data {
|
||||
player: player,
|
||||
main-hand: hand
|
||||
}
|
||||
|
||||
record player-gamemode-change-event-data {
|
||||
player: player,
|
||||
previous-gamemode: game-mode,
|
||||
new-gamemode: game-mode,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-custom-payload-event-data {
|
||||
player: player,
|
||||
channel: string,
|
||||
data: list<u8>
|
||||
}
|
||||
|
||||
enum player-fish-state {
|
||||
fishing,
|
||||
caught-fish,
|
||||
caught-entity,
|
||||
in-ground,
|
||||
failed-attempt,
|
||||
reel-in,
|
||||
bite,
|
||||
}
|
||||
|
||||
record player-fish-event-data {
|
||||
player: player,
|
||||
caught-uuid: option<string>,
|
||||
caught-type: string,
|
||||
hook-uuid: string,
|
||||
state: player-fish-state,
|
||||
hand: hand,
|
||||
exp-to-drop: s32,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-egg-throw-event-data {
|
||||
player: player,
|
||||
egg-uuid: string,
|
||||
hatching: bool,
|
||||
num-hatches: u8,
|
||||
hatching-type: string,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
enum entity-interaction-action {
|
||||
interact,
|
||||
attack,
|
||||
interact-at,
|
||||
}
|
||||
|
||||
enum interact-action {
|
||||
left-click-block,
|
||||
left-click-air,
|
||||
right-click-air,
|
||||
right-click-block,
|
||||
}
|
||||
|
||||
record player-interact-event-data {
|
||||
player: player,
|
||||
action: interact-action,
|
||||
clicked-pos: option<block-position>,
|
||||
item: item-stack,
|
||||
block: string,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-toggle-sneak-event-data {
|
||||
player: player,
|
||||
is-sneaking: bool,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-toggle-sprint-event-data {
|
||||
player: player,
|
||||
is-sprinting: bool,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record player-interact-unknown-entity-event-data {
|
||||
player: player,
|
||||
entity-id: s32,
|
||||
action: entity-interaction-action,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record block-redstone-event-data {
|
||||
target-world: %world,
|
||||
state-id: u16,
|
||||
block-position: block-position,
|
||||
old-current: s32,
|
||||
new-current: s32,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record block-break-event-data {
|
||||
player: option<player>,
|
||||
block: string,
|
||||
block-position: block-position,
|
||||
exp: u32,
|
||||
should-drop: bool,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record block-burn-event-data {
|
||||
igniting-block: string,
|
||||
block: string,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record block-can-build-event-data {
|
||||
block-to-build: string,
|
||||
buildable: bool,
|
||||
player: player,
|
||||
block: string,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record block-grow-event-data {
|
||||
target-world: %world,
|
||||
old-block: string,
|
||||
old-state-id: u16,
|
||||
new-block: string,
|
||||
new-state-id: u16,
|
||||
block-position: block-position,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record block-place-event-data {
|
||||
player: player,
|
||||
block-placed: string,
|
||||
block-placed-against: string,
|
||||
block-position: block-position,
|
||||
can-build: bool,
|
||||
cancelled: bool
|
||||
}
|
||||
record server-command-event-data {
|
||||
command: string,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record spawn-change-event-data {
|
||||
target-world: %world,
|
||||
previous-position: block-position,
|
||||
previous-yaw: f32,
|
||||
previous-pitch: f32,
|
||||
new-position: block-position,
|
||||
new-yaw: f32,
|
||||
new-pitch: f32
|
||||
}
|
||||
|
||||
record server-broadcast-event-data {
|
||||
message: text-component,
|
||||
sender: text-component,
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
enum event-type {
|
||||
player-join-event,
|
||||
player-leave-event,
|
||||
player-login-event,
|
||||
player-chat-event,
|
||||
player-command-send-event,
|
||||
player-permission-check-event,
|
||||
player-move-event,
|
||||
player-teleport-event,
|
||||
player-change-world-event,
|
||||
player-exp-change-event,
|
||||
player-item-held-event,
|
||||
player-changed-main-hand-event,
|
||||
player-gamemode-change-event,
|
||||
player-custom-payload-event,
|
||||
player-fish-event,
|
||||
player-egg-throw-event,
|
||||
player-interact-unknown-entity-event,
|
||||
player-interact-event,
|
||||
player-toggle-sneak-event,
|
||||
player-toggle-sprint-event,
|
||||
block-redstone-event,
|
||||
block-break-event,
|
||||
block-burn-event,
|
||||
block-can-build-event,
|
||||
block-grow-event,
|
||||
block-place-event,
|
||||
server-command-event,
|
||||
spawn-change-event,
|
||||
server-broadcast-event,
|
||||
}
|
||||
|
||||
variant event {
|
||||
player-join-event(player-join-event-data),
|
||||
player-leave-event(player-leave-event-data),
|
||||
player-login-event(player-login-event-data),
|
||||
player-chat-event(player-chat-event-data),
|
||||
player-command-send-event(player-command-send-event-data),
|
||||
player-permission-check-event(player-permission-check-event-data),
|
||||
player-move-event(player-move-event-data),
|
||||
player-teleport-event(player-teleport-event-data),
|
||||
player-change-world-event(player-change-world-event-data),
|
||||
player-exp-change-event(player-exp-change-event-data),
|
||||
player-item-held-event(player-item-held-event-data),
|
||||
player-changed-main-hand-event(player-changed-main-hand-event-data),
|
||||
player-gamemode-change-event(player-gamemode-change-event-data),
|
||||
player-custom-payload-event(player-custom-payload-event-data),
|
||||
player-fish-event(player-fish-event-data),
|
||||
player-egg-throw-event(player-egg-throw-event-data),
|
||||
player-interact-unknown-entity-event(player-interact-unknown-entity-event-data),
|
||||
player-interact-event(player-interact-event-data),
|
||||
player-toggle-sneak-event(player-toggle-sneak-event-data),
|
||||
player-toggle-sprint-event(player-toggle-sprint-event-data),
|
||||
block-redstone-event(block-redstone-event-data),
|
||||
block-break-event(block-break-event-data),
|
||||
block-burn-event(block-burn-event-data),
|
||||
block-can-build-event(block-can-build-event-data),
|
||||
block-grow-event(block-grow-event-data),
|
||||
block-place-event(block-place-event-data),
|
||||
server-command-event(server-command-event-data),
|
||||
spawn-change-event(spawn-change-event-data),
|
||||
server-broadcast-event(server-broadcast-event-data),
|
||||
}
|
||||
}
|
||||
38
src/pumpkin_api/wit_files/gui.wit
Normal file
38
src/pumpkin_api/wit_files/gui.wit
Normal file
@ -0,0 +1,38 @@
|
||||
interface gui {
|
||||
use text.{text-component};
|
||||
use common.{item-stack};
|
||||
|
||||
enum gui-type {
|
||||
generic-9x1,
|
||||
generic-9x2,
|
||||
generic-9x3,
|
||||
generic-9x4,
|
||||
generic-9x5,
|
||||
generic-9x6,
|
||||
generic-3x3,
|
||||
crafter-3x3,
|
||||
anvil,
|
||||
beacon,
|
||||
blast-furnace,
|
||||
brewing-stand,
|
||||
crafting,
|
||||
enchantment,
|
||||
furnace,
|
||||
grindstone,
|
||||
hopper,
|
||||
lectern,
|
||||
loom,
|
||||
merchant,
|
||||
shulker-box,
|
||||
smithing,
|
||||
smoker,
|
||||
cartography-table,
|
||||
stonecutter,
|
||||
}
|
||||
|
||||
resource gui {
|
||||
constructor(%type: gui-type, title: text-component);
|
||||
set-item: func(slot: u32, item: item-stack);
|
||||
get-item: func(slot: u32) -> option<item-stack>;
|
||||
}
|
||||
}
|
||||
21
src/pumpkin_api/wit_files/i18n.wit
Normal file
21
src/pumpkin_api/wit_files/i18n.wit
Normal file
@ -0,0 +1,21 @@
|
||||
interface i18n {
|
||||
use common.{locale};
|
||||
|
||||
/// Retrieves a translated string from the host.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `key`: The namespaced translation key (e.g. `pumpkin:my_key`).
|
||||
/// * `locale`: The target locale.
|
||||
///
|
||||
/// # Returns
|
||||
/// The localized string, falling back to English or the key itself.
|
||||
translate: func(key: string, locale: locale) -> string;
|
||||
|
||||
/// Loads custom translations from a JSON string.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `namespace`: The namespace to associate these keys with.
|
||||
/// * `json`: A JSON string containing a flat map of translations.
|
||||
/// * `locale`: The target locale for these translations.
|
||||
load-translations: func(namespace: string, json: string, locale: locale);
|
||||
}
|
||||
14
src/pumpkin_api/wit_files/log.wit
Normal file
14
src/pumpkin_api/wit_files/log.wit
Normal file
@ -0,0 +1,14 @@
|
||||
interface logging {
|
||||
enum level {
|
||||
trace,
|
||||
debug,
|
||||
info,
|
||||
warn,
|
||||
error,
|
||||
}
|
||||
|
||||
/// log any general purpose message
|
||||
log: func(level: level, message: string);
|
||||
/// This function is meant to be used by the tracing crate.
|
||||
log-tracing: func(event: list<u8>);
|
||||
}
|
||||
15
src/pumpkin_api/wit_files/metadata.wit
Normal file
15
src/pumpkin_api/wit_files/metadata.wit
Normal file
@ -0,0 +1,15 @@
|
||||
/// Plugin metadata describing the plugin and its compatibility.
|
||||
interface metadata {
|
||||
record plugin-metadata {
|
||||
/// Name of the plugin.
|
||||
name: string,
|
||||
/// Plugin version (semver).
|
||||
version: string,
|
||||
/// Plugin authors.
|
||||
authors: list<string>,
|
||||
/// Short description of the plugin.
|
||||
description: string,
|
||||
}
|
||||
|
||||
get-metadata: func() -> plugin-metadata;
|
||||
}
|
||||
46
src/pumpkin_api/wit_files/permission.wit
Normal file
46
src/pumpkin_api/wit_files/permission.wit
Normal file
@ -0,0 +1,46 @@
|
||||
interface permission {
|
||||
/// Represents the player's permission level
|
||||
///
|
||||
/// Permission levels determine the player's access to commands and server operations.
|
||||
/// Each numeric level corresponds to a specific role:
|
||||
/// - `Zero`: `normal`: Player can use basic commands.
|
||||
/// - `One`: `moderator`: Player can bypass spawn protection.
|
||||
/// - `Two`: `gamemaster`: Player or executor can use more commands and player can use command blocks.
|
||||
/// - `Three`: `admin`: Player or executor can use commands related to multiplayer management.
|
||||
/// - `Four`: `owner`: Player or executor can use all of the commands, including commands related to server management.
|
||||
enum permission-level {
|
||||
zero,
|
||||
one,
|
||||
two,
|
||||
three,
|
||||
four,
|
||||
}
|
||||
|
||||
/// Describes the default behavior for permissions
|
||||
variant permission-default {
|
||||
/// Permission is not granted by default
|
||||
deny,
|
||||
/// Permission is granted by default
|
||||
allow,
|
||||
/// Permission is granted by default to operators
|
||||
op(permission-level),
|
||||
}
|
||||
|
||||
/// A child permission entry
|
||||
record permission-child {
|
||||
node: string,
|
||||
value: bool,
|
||||
}
|
||||
|
||||
/// Defines a permission node in the system
|
||||
record permission {
|
||||
/// The full node name (e.g., "minecraft:command.gamemode")
|
||||
node: string,
|
||||
/// Description of what this permission does
|
||||
description: string,
|
||||
/// The default value of this permission
|
||||
default: permission-default,
|
||||
/// Children nodes that are affected by this permission
|
||||
children: list<permission-child>,
|
||||
}
|
||||
}
|
||||
172
src/pumpkin_api/wit_files/player.wit
Normal file
172
src/pumpkin_api/wit_files/player.wit
Normal file
@ -0,0 +1,172 @@
|
||||
/// Represents a player connected to the Minecraft server.
|
||||
interface player {
|
||||
use common.{hand, item-stack, position, game-mode};
|
||||
use %world.{%world};
|
||||
use permission.{permission-level};
|
||||
use text.{text-component};
|
||||
use gui.{gui};
|
||||
|
||||
/// Various abilities a player can have.
|
||||
record player-abilities {
|
||||
/// Whether the player is invulnerable to damage.
|
||||
invulnerable: bool,
|
||||
/// Whether the player is currently flying.
|
||||
flying: bool,
|
||||
/// Whether the player is allowed to fly.
|
||||
allow-flying: bool,
|
||||
/// Whether the player is in creative mode.
|
||||
creative: bool,
|
||||
/// Whether the player can modify the world.
|
||||
allow-modify-world: bool,
|
||||
/// The speed at which the player flies.
|
||||
fly-speed: f32,
|
||||
/// The speed at which the player walks.
|
||||
walk-speed: f32,
|
||||
}
|
||||
|
||||
/// A handle to a player on the server.
|
||||
resource player {
|
||||
/// Returns the player's unique UUID as a string.
|
||||
get-id: func () -> string;
|
||||
/// Returns the player's username.
|
||||
get-name: func () -> string;
|
||||
|
||||
// Basic state
|
||||
|
||||
/// Returns the player's current position in the world.
|
||||
get-position: func () -> position;
|
||||
/// Returns the player's current yaw (horizontal rotation).
|
||||
get-yaw: func () -> f32;
|
||||
/// Returns the player's current pitch (vertical rotation).
|
||||
get-pitch: func () -> f32;
|
||||
/// Returns the world the player is currently in.
|
||||
get-world: func () -> %world;
|
||||
/// Returns the player's current game mode.
|
||||
get-gamemode: func () -> game-mode;
|
||||
/// Changes the player's game mode. Returns true if successful.
|
||||
set-gamemode: func (mode: game-mode) -> bool;
|
||||
/// Returns the player's locale (e.g., "en_us").
|
||||
get-locale: func () -> string;
|
||||
/// Returns the player's current ping in milliseconds.
|
||||
get-ping: func () -> u32;
|
||||
|
||||
// Permissions & metadata
|
||||
|
||||
/// Returns the player's permission level (0-4).
|
||||
get-permission-level: func () -> permission-level;
|
||||
/// Sets the player's permission level.
|
||||
set-permission-level: func (level: permission-level);
|
||||
/// Checks if the player has a specific permission node.
|
||||
has-permission: func (node: string) -> bool;
|
||||
/// Returns the player's display name, which may include formatting.
|
||||
get-display-name: func () -> text-component;
|
||||
|
||||
// Messaging & titles
|
||||
|
||||
/// Sends a system message to the player's chat.
|
||||
send-system-message: func (text: text-component, overlay: bool);
|
||||
/// Shows a large title on the player's screen.
|
||||
show-title: func (text: text-component);
|
||||
/// Shows a smaller subtitle on the player's screen.
|
||||
show-subtitle: func (text: text-component);
|
||||
/// Shows a message in the action bar area.
|
||||
show-actionbar: func (text: text-component);
|
||||
/// Sets the fade-in, stay, and fade-out times for titles.
|
||||
send-title-animation: func (fade-in: s32, stay: s32, fade-out: s32);
|
||||
|
||||
// Teleport & kick
|
||||
|
||||
/// Teleports the player to a position in a world.
|
||||
teleport: func (position: position, yaw: option<f32>, pitch: option<f32>, %world: %world);
|
||||
/// Teleports the player to another world at a specific position.
|
||||
teleport-world: func (world-ref: %world, position: position, yaw: option<f32>, pitch: option<f32>);
|
||||
/// Kicks the player from the server with the specified reason.
|
||||
kick: func (message: text-component);
|
||||
/// Forces the player to respawn.
|
||||
respawn: func ();
|
||||
|
||||
/// Opens a GUI for the player.
|
||||
open-gui: func (gui-ref: gui);
|
||||
|
||||
/// Bans the player with an optional reason.
|
||||
ban: func (reason: option<text-component>);
|
||||
/// Bans the player's IP address with an optional reason.
|
||||
ban-ip: func (reason: option<text-component>);
|
||||
|
||||
// Inventory
|
||||
|
||||
/// Returns the index of the currently selected hotbar slot (0-8).
|
||||
get-selected-slot: func () -> u8;
|
||||
/// Returns the item currently in the specified hand.
|
||||
get-item-in-hand: func (hand: hand) -> option<item-stack>;
|
||||
/// Returns the item in the specified inventory slot.
|
||||
get-inventory-item: func (slot: u8) -> option<item-stack>;
|
||||
|
||||
// Status
|
||||
|
||||
/// Returns the player's current health.
|
||||
get-health: func () -> f32;
|
||||
/// Sets the player's current health.
|
||||
set-health: func (health: f32);
|
||||
/// Returns the player's maximum health.
|
||||
get-max-health: func () -> f32;
|
||||
/// Sets the player's maximum health.
|
||||
set-max-health: func (max-health: f32);
|
||||
/// Returns the player's food level (0-20).
|
||||
get-food-level: func () -> u8;
|
||||
/// Sets the player's food level.
|
||||
set-food-level: func (food-level: u8);
|
||||
/// Returns the player's food saturation level.
|
||||
get-saturation: func () -> f32;
|
||||
/// Sets the player's food saturation level.
|
||||
set-saturation: func (saturation: f32);
|
||||
/// Returns the player's food exhaustion level.
|
||||
get-exhaustion: func () -> f32;
|
||||
/// Sets the player's food exhaustion level.
|
||||
set-exhaustion: func (exhaustion: f32);
|
||||
/// Returns the player's current absorption amount.
|
||||
get-absorption: func () -> f32;
|
||||
/// Sets the player's current absorption amount.
|
||||
set-absorption: func (absorption: f32);
|
||||
|
||||
/// Returns the player's total experience level.
|
||||
get-experience-level: func() -> s32;
|
||||
/// Returns the player's progress toward the next level (0.0 to 1.0).
|
||||
get-experience-progress: func() -> f32;
|
||||
/// Returns the total experience points the player has.
|
||||
get-experience-points: func() -> s32;
|
||||
/// Sets the player's total experience level.
|
||||
set-experience-level: func(level: s32);
|
||||
/// Sets the player's progress toward the next level.
|
||||
set-experience-progress: func(progress: f32);
|
||||
/// Sets the player's total experience points.
|
||||
set-experience-points: func(points: s32);
|
||||
/// Adds experience levels to the player.
|
||||
add-experience-levels: func(levels: s32);
|
||||
/// Adds experience points to the player.
|
||||
add-experience-points: func(points: s32);
|
||||
|
||||
/// Returns whether the player is currently sneaking.
|
||||
is-sneaking: func() -> bool;
|
||||
/// Sets whether the player is currently sneaking.
|
||||
set-sneaking: func(sneaking: bool);
|
||||
/// Returns whether the player is currently sprinting.
|
||||
is-sprinting: func() -> bool;
|
||||
/// Sets whether the player is currently sprinting.
|
||||
set-sprinting: func(sprinting: bool);
|
||||
/// Returns whether the player is currently on the ground.
|
||||
is-on-ground: func() -> bool;
|
||||
/// Returns whether the player is currently flying.
|
||||
is-flying: func() -> bool;
|
||||
/// Sets whether the player should be flying.
|
||||
set-flying: func(flying: bool);
|
||||
|
||||
/// Returns the player's current abilities.
|
||||
get-abilities: func() -> player-abilities;
|
||||
/// Updates the player's abilities.
|
||||
set-abilities: func(abilities: player-abilities);
|
||||
|
||||
/// Returns the player's IP address.
|
||||
get-ip: func() -> string;
|
||||
}
|
||||
}
|
||||
61
src/pumpkin_api/wit_files/plugin.wit
Normal file
61
src/pumpkin_api/wit_files/plugin.wit
Normal file
@ -0,0 +1,61 @@
|
||||
/// The main entry point for a Pumpkin plugin.
|
||||
/// This world defines the exports that the plugin must provide to the host
|
||||
/// and the imports that the host provides to the plugin.
|
||||
package pumpkin:plugin;
|
||||
|
||||
world plugin {
|
||||
use context.{context};
|
||||
use event.{event};
|
||||
use server.{server as server-instance};
|
||||
use command.{command-sender, consumed-args, command-error};
|
||||
|
||||
// --- Host-provided imports ---
|
||||
|
||||
/// Provides logging capabilities to the plugin.
|
||||
import logging;
|
||||
/// Provides GUI creation and management.
|
||||
import gui;
|
||||
/// Provides scoreboard management.
|
||||
import scoreboard;
|
||||
/// Provides global server information and player lookup.
|
||||
import server;
|
||||
/// Provides text component building and formatting.
|
||||
import text;
|
||||
/// Provides command registration and argument parsing.
|
||||
import command;
|
||||
/// Provides the plugin execution context.
|
||||
import context;
|
||||
/// Provides internationalization and translation support.
|
||||
import i18n;
|
||||
/// Provides task scheduling for delayed or repeating logic.
|
||||
import scheduler;
|
||||
|
||||
// --- Plugin-provided exports ---
|
||||
|
||||
/// Called by the host once to initialize the plugin.
|
||||
/// Internal use only; plugins should use the `register_plugin!` macro.
|
||||
export init-plugin: func();
|
||||
|
||||
/// Called when the plugin is being loaded.
|
||||
/// Use this to register commands, events, and perform initial setup.
|
||||
export on-load: func(context: context) -> result<_, string>;
|
||||
|
||||
/// Called when the plugin is being unloaded.
|
||||
/// Use this to save data and clean up resources.
|
||||
export on-unload: func(context: context) -> result<_, string>;
|
||||
|
||||
/// Provides plugin metadata (name, version, etc.) to the host.
|
||||
export metadata;
|
||||
|
||||
/// Common types used across the API.
|
||||
export common;
|
||||
|
||||
/// Dispatches an event to the plugin for handling.
|
||||
export handle-event: func(event-id: u32, server: server-instance, event: event) -> event;
|
||||
|
||||
/// Dispatches a command execution to the plugin.
|
||||
export handle-command: func(command-id: u32, sender: command-sender, server: server-instance, args: consumed-args) -> result<s32, command-error>;
|
||||
|
||||
/// Dispatches a scheduled task execution to the plugin.
|
||||
export handle-task: func(handler-id: u32, server: server-instance);
|
||||
}
|
||||
440
src/pumpkin_api/wit_files/poll_loop.py
Normal file
440
src/pumpkin_api/wit_files/poll_loop.py
Normal file
@ -0,0 +1,440 @@
|
||||
"""Defines a custom `asyncio` event loop backed by `wasi:io/poll#poll`.
|
||||
|
||||
This also includes helper classes and functions for working with `wasi:http`.
|
||||
|
||||
This is only useful for `wasi:http@0.2.x`; `wasi:http@0.3.x` uses a different
|
||||
mechanism to model concurrency.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import socket
|
||||
import subprocess
|
||||
|
||||
from componentize_py_types import Ok, Err
|
||||
from wit_world.imports import types, streams, poll, outgoing_handler
|
||||
from wit_world.imports.types import (
|
||||
IncomingBody,
|
||||
OutgoingBody,
|
||||
OutgoingRequest,
|
||||
IncomingResponse,
|
||||
)
|
||||
from wit_world.imports.streams import StreamError_Closed, InputStream
|
||||
from wit_world.imports.poll import Pollable
|
||||
from typing import Optional, cast
|
||||
|
||||
# Maximum number of bytes to read at a time
|
||||
READ_SIZE: int = 16 * 1024
|
||||
|
||||
|
||||
async def send(request: OutgoingRequest) -> IncomingResponse:
|
||||
"""Send the specified request and wait asynchronously for the response."""
|
||||
|
||||
future = outgoing_handler.handle(request, None)
|
||||
|
||||
while True:
|
||||
response = future.get()
|
||||
if response is None:
|
||||
await register(cast(PollLoop, asyncio.get_event_loop()), future.subscribe())
|
||||
else:
|
||||
if isinstance(response, Ok):
|
||||
if isinstance(response.value, Ok):
|
||||
return response.value.value
|
||||
else:
|
||||
raise response.value
|
||||
else:
|
||||
raise response
|
||||
|
||||
|
||||
class Stream:
|
||||
"""Reader abstraction over `wasi:http/types#incoming-body`."""
|
||||
|
||||
def __init__(self, body: IncomingBody):
|
||||
self.body: Optional[IncomingBody] = body
|
||||
self.stream: Optional[InputStream] = body.stream()
|
||||
|
||||
async def next(self) -> Optional[bytes]:
|
||||
"""Wait for the next chunk of data to arrive on the stream.
|
||||
|
||||
This will return `None` when the end of the stream has been reached.
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
if self.stream is None:
|
||||
return None
|
||||
else:
|
||||
buffer = self.stream.read(READ_SIZE)
|
||||
if len(buffer) == 0:
|
||||
await register(
|
||||
cast(PollLoop, asyncio.get_event_loop()),
|
||||
self.stream.subscribe(),
|
||||
)
|
||||
else:
|
||||
return buffer
|
||||
except Err as e:
|
||||
if isinstance(e.value, StreamError_Closed):
|
||||
if self.stream is not None:
|
||||
self.stream.__exit__(None, None, None)
|
||||
self.stream = None
|
||||
if self.body is not None:
|
||||
IncomingBody.finish(self.body)
|
||||
self.body = None
|
||||
else:
|
||||
raise e
|
||||
|
||||
|
||||
class Sink:
|
||||
"""Writer abstraction over `wasi:http/types#outgoing-body`."""
|
||||
|
||||
def __init__(self, body: OutgoingBody):
|
||||
self.body = body
|
||||
self.stream = body.write()
|
||||
|
||||
async def send(self, chunk: bytes):
|
||||
"""Write the specified bytes to the sink.
|
||||
|
||||
This may need to yield according to the backpressure requirements of the sink.
|
||||
"""
|
||||
offset = 0
|
||||
flushing = False
|
||||
while True:
|
||||
count = self.stream.check_write()
|
||||
if count == 0:
|
||||
await register(
|
||||
cast(PollLoop, asyncio.get_event_loop()), self.stream.subscribe()
|
||||
)
|
||||
elif offset == len(chunk):
|
||||
if flushing:
|
||||
return
|
||||
else:
|
||||
self.stream.flush()
|
||||
flushing = True
|
||||
else:
|
||||
count = min(count, len(chunk) - offset)
|
||||
self.stream.write(chunk[offset : offset + count])
|
||||
offset += count
|
||||
|
||||
def close(self):
|
||||
"""Close the stream, indicating no further data will be written."""
|
||||
|
||||
self.stream.__exit__(None, None, None)
|
||||
self.stream = None
|
||||
OutgoingBody.finish(self.body, None)
|
||||
self.body = None
|
||||
|
||||
|
||||
class PollLoop(asyncio.AbstractEventLoop):
|
||||
"""Custom `asyncio` event loop backed by `wasi:io/poll#poll`."""
|
||||
|
||||
def __init__(self):
|
||||
self.wakers = []
|
||||
self.running = False
|
||||
self.handles = []
|
||||
self.exception = None
|
||||
|
||||
def get_debug(self):
|
||||
return False
|
||||
|
||||
def run_until_complete(self, future):
|
||||
future = asyncio.ensure_future(future, loop=self)
|
||||
|
||||
self.running = True
|
||||
asyncio.events._set_running_loop(self)
|
||||
while self.running and not future.done():
|
||||
handles = self.handles
|
||||
self.handles = []
|
||||
for handle in handles:
|
||||
if not handle._cancelled:
|
||||
handle._run()
|
||||
|
||||
if self.wakers:
|
||||
[pollables, wakers] = list(map(list, zip(*self.wakers)))
|
||||
|
||||
new_wakers = []
|
||||
ready = [False] * len(pollables)
|
||||
for index in poll.poll(pollables):
|
||||
ready[index] = True
|
||||
|
||||
for (ready, pollable), waker in zip(zip(ready, pollables), wakers):
|
||||
if ready:
|
||||
pollable.__exit__(None, None, None)
|
||||
waker.set_result(None)
|
||||
else:
|
||||
new_wakers.append((pollable, waker))
|
||||
|
||||
self.wakers = new_wakers
|
||||
|
||||
if self.exception is not None:
|
||||
raise self.exception
|
||||
|
||||
return future.result()
|
||||
|
||||
def is_running(self):
|
||||
return self.running
|
||||
|
||||
def is_closed(self):
|
||||
return not self.running
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
def close(self):
|
||||
self.running = False
|
||||
|
||||
def shutdown_asyncgens(self):
|
||||
pass
|
||||
|
||||
def call_exception_handler(self, context):
|
||||
self.exception = context.get("exception", None)
|
||||
|
||||
def call_soon(self, callback, *args, context=None):
|
||||
handle = asyncio.Handle(callback, args, self, context)
|
||||
self.handles.append(handle)
|
||||
return handle
|
||||
|
||||
def create_task(self, coroutine):
|
||||
return asyncio.Task(coroutine, loop=self)
|
||||
|
||||
def create_future(self):
|
||||
return asyncio.Future(loop=self)
|
||||
|
||||
# The remaining methods should be irrelevant for our purposes and thus unimplemented
|
||||
|
||||
def run_forever(self):
|
||||
raise NotImplementedError
|
||||
|
||||
async def shutdown_default_executor(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def _timer_handle_cancelled(self, handle):
|
||||
raise NotImplementedError
|
||||
|
||||
def call_later(self, delay, callback, *args, context=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def call_at(self, when, callback, *args, context=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def time(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def call_soon_threadsafe(self, callback, *args, context=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def run_in_executor(self, executor, func, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_default_executor(self, executor):
|
||||
raise NotImplementedError
|
||||
|
||||
async def getaddrinfo(self, host, port, *, family=0, type=0, proto=0, flags=0):
|
||||
raise NotImplementedError
|
||||
|
||||
async def getnameinfo(self, sockaddr, flags=0):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_connection(
|
||||
self,
|
||||
protocol_factory,
|
||||
host=None,
|
||||
port=None,
|
||||
*,
|
||||
ssl=None,
|
||||
family=0,
|
||||
proto=0,
|
||||
flags=0,
|
||||
sock=None,
|
||||
local_addr=None,
|
||||
server_hostname=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
happy_eyeballs_delay=None,
|
||||
interleave=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_server(
|
||||
self,
|
||||
protocol_factory,
|
||||
host=None,
|
||||
port=None,
|
||||
*,
|
||||
family=socket.AF_UNSPEC,
|
||||
flags=socket.AI_PASSIVE,
|
||||
sock=None,
|
||||
backlog=100,
|
||||
ssl=None,
|
||||
reuse_address=None,
|
||||
reuse_port=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
start_serving=True,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sendfile(self, transport, file, offset=0, count=None, *, fallback=True):
|
||||
raise NotImplementedError
|
||||
|
||||
async def start_tls(
|
||||
self,
|
||||
transport,
|
||||
protocol,
|
||||
sslcontext,
|
||||
*,
|
||||
server_side=False,
|
||||
server_hostname=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_connection(
|
||||
self,
|
||||
protocol_factory,
|
||||
path=None,
|
||||
*,
|
||||
ssl=None,
|
||||
sock=None,
|
||||
server_hostname=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_unix_server(
|
||||
self,
|
||||
protocol_factory,
|
||||
path=None,
|
||||
*,
|
||||
sock=None,
|
||||
backlog=100,
|
||||
ssl=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
start_serving=True,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_accepted_socket(
|
||||
self,
|
||||
protocol_factory,
|
||||
sock,
|
||||
*,
|
||||
ssl=None,
|
||||
ssl_handshake_timeout=None,
|
||||
ssl_shutdown_timeout=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def create_datagram_endpoint(
|
||||
self,
|
||||
protocol_factory,
|
||||
local_addr=None,
|
||||
remote_addr=None,
|
||||
*,
|
||||
family=0,
|
||||
proto=0,
|
||||
flags=0,
|
||||
reuse_address=None,
|
||||
reuse_port=None,
|
||||
allow_broadcast=None,
|
||||
sock=None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_read_pipe(self, protocol_factory, pipe):
|
||||
raise NotImplementedError
|
||||
|
||||
async def connect_write_pipe(self, protocol_factory, pipe):
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_shell(
|
||||
self,
|
||||
protocol_factory,
|
||||
cmd,
|
||||
*,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
**kwargs,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
async def subprocess_exec(
|
||||
self,
|
||||
protocol_factory,
|
||||
*args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
**kwargs,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_reader(self, fd, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_reader(self, fd):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_writer(self, fd, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_writer(self, fd):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv(self, sock, nbytes):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recv_into(self, sock, buf):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom(self, sock, bufsize):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_recvfrom_into(self, sock, buf, nbytes=0):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendall(self, sock, data):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendto(self, sock, data, address):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_connect(self, sock, address):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_accept(self, sock):
|
||||
raise NotImplementedError
|
||||
|
||||
async def sock_sendfile(self, sock, file, offset=0, count=None, *, fallback=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def add_signal_handler(self, sig, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def remove_signal_handler(self, sig):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_task_factory(self, factory):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_task_factory(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_exception_handler(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_exception_handler(self, handler):
|
||||
raise NotImplementedError
|
||||
|
||||
def default_exception_handler(self, context):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_debug(self, enabled):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
async def register(loop: PollLoop, pollable: Pollable):
|
||||
waker = loop.create_future()
|
||||
loop.wakers.append((pollable, waker))
|
||||
await waker
|
||||
24
src/pumpkin_api/wit_files/scheduler.wit
Normal file
24
src/pumpkin_api/wit_files/scheduler.wit
Normal file
@ -0,0 +1,24 @@
|
||||
/// Provides functionality to schedule tasks to be executed later on the server.
|
||||
interface scheduler {
|
||||
/// Schedules a task to be executed once after the specified number of ticks.
|
||||
///
|
||||
/// * `handler-id`: The unique ID of the handler to call when the task executes.
|
||||
/// * `delay-ticks`: The number of game ticks to wait before execution (20 ticks = 1 second).
|
||||
///
|
||||
/// Returns a unique task ID that can be used to cancel the task.
|
||||
schedule-delayed-task: func(handler-id: u32, delay-ticks: u64) -> u32;
|
||||
|
||||
/// Schedules a task to be executed repeatedly.
|
||||
///
|
||||
/// * `handler-id`: The unique ID of the handler to call when the task executes.
|
||||
/// * `delay-ticks`: The number of game ticks to wait before the first execution.
|
||||
/// * `period-ticks`: The number of game ticks between subsequent executions.
|
||||
///
|
||||
/// Returns a unique task ID that can be used to cancel the task.
|
||||
schedule-repeating-task: func(handler-id: u32, delay-ticks: u64, period-ticks: u64) -> u32;
|
||||
|
||||
/// Cancels a scheduled task if it hasn't finished yet.
|
||||
///
|
||||
/// * `task-id`: The ID of the task to cancel.
|
||||
cancel-task: func(task-id: u32);
|
||||
}
|
||||
72
src/pumpkin_api/wit_files/scoreboard.wit
Normal file
72
src/pumpkin_api/wit_files/scoreboard.wit
Normal file
@ -0,0 +1,72 @@
|
||||
interface scoreboard {
|
||||
use text.{text-component};
|
||||
use common.{named-color};
|
||||
|
||||
enum render-type {
|
||||
integer,
|
||||
hearts
|
||||
}
|
||||
|
||||
enum display-slot {
|
||||
player-list,
|
||||
sidebar,
|
||||
below-name,
|
||||
sidebar-team-black,
|
||||
sidebar-team-dark-blue,
|
||||
sidebar-team-dark-green,
|
||||
sidebar-team-dark-aqua,
|
||||
sidebar-team-dark-red,
|
||||
sidebar-team-dark-purple,
|
||||
sidebar-team-gold,
|
||||
sidebar-team-gray,
|
||||
sidebar-team-dark-gray,
|
||||
sidebar-team-blue,
|
||||
sidebar-team-green,
|
||||
sidebar-team-aqua,
|
||||
sidebar-team-red,
|
||||
sidebar-team-light-purple,
|
||||
sidebar-team-yellow,
|
||||
sidebar-team-white,
|
||||
}
|
||||
|
||||
enum nametag-visibility {
|
||||
always,
|
||||
never,
|
||||
hide-for-other-teams,
|
||||
hide-for-own-team
|
||||
}
|
||||
|
||||
enum collision-rule {
|
||||
always,
|
||||
never,
|
||||
push-other-teams,
|
||||
push-own-team
|
||||
}
|
||||
|
||||
record team-settings {
|
||||
display-name: text-component,
|
||||
friendly-fire: bool,
|
||||
see-friendly-invisibles: bool,
|
||||
nametag-visibility: nametag-visibility,
|
||||
collision-rule: collision-rule,
|
||||
color: named-color,
|
||||
prefix: text-component,
|
||||
suffix: text-component
|
||||
}
|
||||
|
||||
resource scoreboard {
|
||||
add-objective: func(name: string, display-name: text-component, render-type: render-type);
|
||||
remove-objective: func(name: string);
|
||||
set-display-slot: func(slot: display-slot, objective-name: string);
|
||||
|
||||
update-score: func(entity-name: string, objective-name: string, value: s32);
|
||||
remove-score: func(entity-name: string, objective-name: string);
|
||||
|
||||
create-team: func(name: string, settings: team-settings);
|
||||
remove-team: func(name: string);
|
||||
update-team: func(name: string, settings: team-settings);
|
||||
|
||||
add-player-to-team: func(team-name: string, player-name: string);
|
||||
remove-player-from-team: func(team-name: string, player-name: string);
|
||||
}
|
||||
}
|
||||
41
src/pumpkin_api/wit_files/server.wit
Normal file
41
src/pumpkin_api/wit_files/server.wit
Normal file
@ -0,0 +1,41 @@
|
||||
interface server {
|
||||
use player.{player};
|
||||
|
||||
/// Represents the difficulty setting of a Minecraft server.
|
||||
enum difficulty {
|
||||
/// Hostile mobs do not spawn. Players regain health automatically.
|
||||
peaceful,
|
||||
/// Hostile mobs deal less damage.
|
||||
easy,
|
||||
/// Standard Minecraft difficulty.
|
||||
normal,
|
||||
/// Hostile mobs deal more damage.
|
||||
hard,
|
||||
}
|
||||
|
||||
/// Represents the global server instance.
|
||||
resource server {
|
||||
/// Returns the current difficulty level of the server.
|
||||
get-difficulty: func() -> difficulty;
|
||||
|
||||
/// Returns the total number of players currently connected to the server.
|
||||
get-player-count: func() -> u32;
|
||||
|
||||
/// Returns the rolling average Milliseconds Per Tick (MSPT).
|
||||
/// A value below 50.0 is required for a stable 20 TPS.
|
||||
get-mspt: func() -> f64;
|
||||
|
||||
/// Returns the effective Ticks Per Second (TPS).
|
||||
/// Ideal value is 20.0.
|
||||
get-tps: func() -> f64;
|
||||
|
||||
/// Returns a list of all online players across all worlds.
|
||||
get-all-players: func() -> list<player>;
|
||||
|
||||
/// Searches for a player by their exact name.
|
||||
get-player-by-name: func(name: string) -> option<player>;
|
||||
|
||||
/// Searches for a player by their UUID string.
|
||||
get-player-by-uuid: func(id: string) -> option<player>;
|
||||
}
|
||||
}
|
||||
41
src/pumpkin_api/wit_files/text.wit
Normal file
41
src/pumpkin_api/wit_files/text.wit
Normal file
@ -0,0 +1,41 @@
|
||||
interface text {
|
||||
use common.{named-color, rgb-color, argb-color};
|
||||
|
||||
resource text-component {
|
||||
text: static func(plain: string) -> text-component;
|
||||
translate: static func(key: string, %with: list<text-component>) -> text-component;
|
||||
|
||||
add-child: func(child: text-component);
|
||||
add-text: func(text: string);
|
||||
get-text: func() -> string;
|
||||
encode: func() -> list<u8>;
|
||||
|
||||
// Style
|
||||
|
||||
color-named: func(color: named-color);
|
||||
color-rgb: func(color: rgb-color);
|
||||
bold: func(value: bool);
|
||||
italic: func(value: bool);
|
||||
underlined: func(value: bool);
|
||||
strikethrough: func(value: bool);
|
||||
obfuscated: func(value: bool);
|
||||
/// Text inserted into chat when shift-clicked
|
||||
insertion: func(text: string);
|
||||
font: func(font: string);
|
||||
shadow-color: func(color: argb-color);
|
||||
|
||||
// Click events
|
||||
|
||||
click-open-url: func(url: string);
|
||||
click-run-command: func(command: string);
|
||||
click-suggest-command: func(command: string);
|
||||
click-copy-to-clipboard: func(text: string);
|
||||
|
||||
// Hover events
|
||||
|
||||
hover-show-text: func(text: text-component);
|
||||
/// Item data as SNBT string
|
||||
hover-show-item: func(item: string);
|
||||
hover-show-entity: func(entity-type: string, id: string, name: option<text-component>);
|
||||
}
|
||||
}
|
||||
70
src/pumpkin_api/wit_files/wit_world/__init__.py
Normal file
70
src/pumpkin_api/wit_files/wit_world/__init__.py
Normal file
@ -0,0 +1,70 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from .imports import event
|
||||
from .imports import server
|
||||
from .imports import command
|
||||
from .imports import context
|
||||
|
||||
|
||||
class WitWorld(Protocol):
|
||||
|
||||
@abstractmethod
|
||||
def init_plugin(self) -> None:
|
||||
"""
|
||||
--- Plugin-provided exports ---
|
||||
Called by the host once to initialize the plugin.
|
||||
Internal use only; plugins should use the `register_plugin!` macro.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def on_load(self, context: context.Context) -> None:
|
||||
"""
|
||||
Called when the plugin is being loaded.
|
||||
Use this to register commands, events, and perform initial setup.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.str)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def on_unload(self, context: context.Context) -> None:
|
||||
"""
|
||||
Called when the plugin is being unloaded.
|
||||
Use this to save data and clean up resources.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.str)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def handle_event(self, event_id: int, server: server.Server, event: event.Event) -> event.Event:
|
||||
"""
|
||||
Dispatches an event to the plugin for handling.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def handle_command(self, command_id: int, sender: command.CommandSender, server: server.Server, args: command.ConsumedArgs) -> int:
|
||||
"""
|
||||
Dispatches a command execution to the plugin.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.command.CommandError)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def handle_task(self, handler_id: int, server: server.Server) -> None:
|
||||
"""
|
||||
Dispatches a scheduled task execution to the plugin.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
19
src/pumpkin_api/wit_files/wit_world/exports/__init__.py
Normal file
19
src/pumpkin_api/wit_files/wit_world/exports/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..exports import metadata
|
||||
|
||||
class Metadata(Protocol):
|
||||
|
||||
@abstractmethod
|
||||
def get_metadata(self) -> metadata.PluginMetadata:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
22
src/pumpkin_api/wit_files/wit_world/exports/metadata.py
Normal file
22
src/pumpkin_api/wit_files/wit_world/exports/metadata.py
Normal file
@ -0,0 +1,22 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Plugin metadata describing the plugin and its compatibility.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
@dataclass
|
||||
class PluginMetadata:
|
||||
name: str
|
||||
version: str
|
||||
authors: List[str]
|
||||
description: str
|
||||
|
||||
539
src/pumpkin_api/wit_files/wit_world/imports/command.py
Normal file
539
src/pumpkin_api/wit_files/wit_world/imports/command.py
Normal file
@ -0,0 +1,539 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import entity
|
||||
from ..imports import text
|
||||
from ..imports import world
|
||||
from ..imports import player
|
||||
from ..imports import server
|
||||
|
||||
class Gamemode(Enum):
|
||||
SURVIVAL = 0
|
||||
CREATIVE = 1
|
||||
ADVENTURE = 2
|
||||
SPECTATOR = 3
|
||||
|
||||
class BossbarColor(Enum):
|
||||
PINK = 0
|
||||
BLUE = 1
|
||||
RED = 2
|
||||
GREEN = 3
|
||||
YELLOW = 4
|
||||
PURPLE = 5
|
||||
WHITE = 6
|
||||
|
||||
class BossbarStyle(Enum):
|
||||
NO_DIVISION = 0
|
||||
NOTCHES6 = 1
|
||||
NOTCHES10 = 2
|
||||
NOTCHES12 = 3
|
||||
NOTCHES20 = 4
|
||||
|
||||
class SoundCategory(Enum):
|
||||
MASTER = 0
|
||||
MUSIC = 1
|
||||
RECORDS = 2
|
||||
WEATHER = 3
|
||||
BLOCKS = 4
|
||||
HOSTILE = 5
|
||||
NEUTRAL = 6
|
||||
PLAYERS = 7
|
||||
AMBIENT = 8
|
||||
VOICE = 9
|
||||
UI = 10
|
||||
|
||||
class EntityAnchor(Enum):
|
||||
FEET = 0
|
||||
EYES = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Float64:
|
||||
value: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Float32:
|
||||
value: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Int32:
|
||||
value: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number_Int64:
|
||||
value: int
|
||||
|
||||
|
||||
Number = Union[Number_Float64, Number_Float32, Number_Int32, Number_Int64]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class NotInBounds_LowerBound:
|
||||
value: Tuple[Number, Number]
|
||||
|
||||
|
||||
@dataclass
|
||||
class NotInBounds_UpperBound:
|
||||
value: Tuple[Number, Number]
|
||||
|
||||
|
||||
NotInBounds = Union[NotInBounds_LowerBound, NotInBounds_UpperBound]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Entities:
|
||||
value: List[entity.Entity]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Entity:
|
||||
value: entity.Entity
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Players:
|
||||
value: List[player.Player]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BlockPos:
|
||||
value: Tuple[int, int, int]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Pos3d:
|
||||
value: Tuple[float, float, float]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Pos2d:
|
||||
value: Tuple[float, float]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Rotation:
|
||||
value: Tuple[float, bool, float, bool]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_GameMode:
|
||||
value: Gamemode
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Difficulty:
|
||||
value: server.Difficulty
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Item:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_ItemPredicate:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_ResourceLocation:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Block:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BlockPredicate:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BossbarColor:
|
||||
value: BossbarColor
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_BossbarStyle:
|
||||
value: BossbarStyle
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Particle:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Msg:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_TextComponent:
|
||||
value: text.TextComponent
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Time:
|
||||
value: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Num:
|
||||
value: Result[Number, NotInBounds]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Bool:
|
||||
value: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Simple:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_SoundCategory:
|
||||
value: SoundCategory
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_DamageType:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Effect:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_Enchantment:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Arg_EntityAnchor:
|
||||
value: EntityAnchor
|
||||
|
||||
|
||||
Arg = Union[Arg_Entities, Arg_Entity, Arg_Players, Arg_BlockPos, Arg_Pos3d, Arg_Pos2d, Arg_Rotation, Arg_GameMode, Arg_Difficulty, Arg_Item, Arg_ItemPredicate, Arg_ResourceLocation, Arg_Block, Arg_BlockPredicate, Arg_BossbarColor, Arg_BossbarStyle, Arg_Particle, Arg_Msg, Arg_TextComponent, Arg_Time, Arg_Num, Arg_Bool, Arg_Simple, Arg_SoundCategory, Arg_DamageType, Arg_Effect, Arg_Enchantment, Arg_EntityAnchor]
|
||||
|
||||
|
||||
class ConsumedArgs:
|
||||
|
||||
def get_value(self, key: str) -> Arg:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Rcon:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Console:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Player:
|
||||
value: player.Player
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_CommandBlock:
|
||||
value: Tuple[entity.CommandBlockEntity, world.World]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandSenderType_Dummy:
|
||||
pass
|
||||
|
||||
|
||||
CommandSenderType = Union[CommandSenderType_Rcon, CommandSenderType_Console, CommandSenderType_Player, CommandSenderType_CommandBlock, CommandSenderType_Dummy]
|
||||
|
||||
|
||||
class PermissionLevel(Enum):
|
||||
ZERO = 0
|
||||
ONE = 1
|
||||
TWO = 2
|
||||
THREE = 3
|
||||
FOUR = 4
|
||||
|
||||
class CommandSender:
|
||||
|
||||
def get_command_sender_type(self) -> CommandSenderType:
|
||||
raise NotImplementedError
|
||||
def send_message(self, text: text.TextComponent) -> None:
|
||||
raise NotImplementedError
|
||||
def set_success_count(self, count: int) -> None:
|
||||
raise NotImplementedError
|
||||
def is_player(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def is_console(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def as_player(self) -> Optional[player.Player]:
|
||||
raise NotImplementedError
|
||||
def permission_level(self) -> PermissionLevel:
|
||||
raise NotImplementedError
|
||||
def has_permission_level(self, level: PermissionLevel) -> bool:
|
||||
raise NotImplementedError
|
||||
def has_permission(self, server: server.Server, node: str) -> bool:
|
||||
raise NotImplementedError
|
||||
def position(self) -> Optional[Tuple[float, float, float]]:
|
||||
raise NotImplementedError
|
||||
def world(self) -> Optional[world.World]:
|
||||
raise NotImplementedError
|
||||
def get_locale(self) -> common.Locale:
|
||||
raise NotImplementedError
|
||||
def should_receive_feedback(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def should_broadcast_console_to_ops(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def should_track_output(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class StringType(Enum):
|
||||
SINGLE_WORD = 0
|
||||
QUOTABLE = 1
|
||||
GREEDY = 2
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Bool:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Float:
|
||||
value: Tuple[Optional[float], Optional[float]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Double:
|
||||
value: Tuple[Optional[float], Optional[float]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Integer:
|
||||
value: Tuple[Optional[int], Optional[int]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Long:
|
||||
value: Tuple[Optional[int], Optional[int]]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_String:
|
||||
value: StringType
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Entities:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Entity:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Players:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_GameProfile:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_BlockPos:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Position3d:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Position2d:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_BlockState:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_BlockPredicate:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Item:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_ItemPredicate:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Component:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Rotation:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_ResourceLocation:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_EntityAnchor:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Gamemode:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Difficulty:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Time:
|
||||
value: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArgumentType_Resource:
|
||||
value: str
|
||||
|
||||
|
||||
ArgumentType = Union[ArgumentType_Bool, ArgumentType_Float, ArgumentType_Double, ArgumentType_Integer, ArgumentType_Long, ArgumentType_String, ArgumentType_Entities, ArgumentType_Entity, ArgumentType_Players, ArgumentType_GameProfile, ArgumentType_BlockPos, ArgumentType_Position3d, ArgumentType_Position2d, ArgumentType_BlockState, ArgumentType_BlockPredicate, ArgumentType_Item, ArgumentType_ItemPredicate, ArgumentType_Component, ArgumentType_Rotation, ArgumentType_ResourceLocation, ArgumentType_EntityAnchor, ArgumentType_Gamemode, ArgumentType_Difficulty, ArgumentType_Time, ArgumentType_Resource]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_InvalidConsumption:
|
||||
value: Optional[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_InvalidRequirement:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_PermissionDenied:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandError_CommandFailed:
|
||||
value: text.TextComponent
|
||||
|
||||
|
||||
CommandError = Union[CommandError_InvalidConsumption, CommandError_InvalidRequirement, CommandError_PermissionDenied, CommandError_CommandFailed]
|
||||
|
||||
|
||||
class CommandNode:
|
||||
|
||||
@classmethod
|
||||
def literal(cls, name: str) -> Self:
|
||||
raise NotImplementedError
|
||||
@classmethod
|
||||
def argument(cls, name: str, arg_type: ArgumentType) -> Self:
|
||||
raise NotImplementedError
|
||||
def then(self, node: Self) -> None:
|
||||
raise NotImplementedError
|
||||
def execute_with_handler_id(self, handler_id: int) -> None:
|
||||
raise NotImplementedError
|
||||
def require_with_handler_id(self, handler_id: int) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Command:
|
||||
|
||||
def __init__(self, names: List[str], description: str) -> None:
|
||||
"""
|
||||
First name is primary, rest are aliases
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def then(self, node: CommandNode) -> None:
|
||||
raise NotImplementedError
|
||||
def execute_with_handler_id(self, handler_id: int) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
213
src/pumpkin_api/wit_files/wit_world/imports/common.py
Normal file
213
src/pumpkin_api/wit_files/wit_world/imports/common.py
Normal file
@ -0,0 +1,213 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Provides common types and utilities used across the entire plugin API.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class Hand(Enum):
|
||||
"""
|
||||
Represents the hands of a player.
|
||||
"""
|
||||
LEFT = 0
|
||||
RIGHT = 1
|
||||
|
||||
class GameMode(Enum):
|
||||
"""
|
||||
Represents the game modes available in Minecraft.
|
||||
"""
|
||||
SURVIVAL = 0
|
||||
CREATIVE = 1
|
||||
ADVENTURE = 2
|
||||
SPECTATOR = 3
|
||||
|
||||
class NamedColor(Enum):
|
||||
"""
|
||||
The 16 base Minecraft colors.
|
||||
"""
|
||||
BLACK = 0
|
||||
DARK_BLUE = 1
|
||||
DARK_GREEN = 2
|
||||
DARK_AQUA = 3
|
||||
DARK_RED = 4
|
||||
DARK_PURPLE = 5
|
||||
GOLD = 6
|
||||
GRAY = 7
|
||||
DARK_GRAY = 8
|
||||
BLUE = 9
|
||||
GREEN = 10
|
||||
AQUA = 11
|
||||
RED = 12
|
||||
LIGHT_PURPLE = 13
|
||||
YELLOW = 14
|
||||
WHITE = 15
|
||||
|
||||
@dataclass
|
||||
class RgbColor:
|
||||
"""
|
||||
An RGB color represented by its red, green, and blue components.
|
||||
"""
|
||||
r: int
|
||||
g: int
|
||||
b: int
|
||||
|
||||
@dataclass
|
||||
class ArgbColor:
|
||||
"""
|
||||
An ARGB color with alpha (transparency) channel.
|
||||
"""
|
||||
a: int
|
||||
r: int
|
||||
g: int
|
||||
b: int
|
||||
|
||||
@dataclass
|
||||
class ItemStack:
|
||||
"""
|
||||
Represents a stack of items with its type and count.
|
||||
"""
|
||||
registry_key: str
|
||||
count: int
|
||||
|
||||
class Locale(Enum):
|
||||
"""
|
||||
All Minecraft-supported locales.
|
||||
"""
|
||||
AF_ZA = 0
|
||||
AR_SA = 1
|
||||
AST_ES = 2
|
||||
AZ_AZ = 3
|
||||
BA_RU = 4
|
||||
BAR = 5
|
||||
BE_BY = 6
|
||||
BG_BG = 7
|
||||
BR_FR = 8
|
||||
BRB = 9
|
||||
BS_BA = 10
|
||||
CA_ES = 11
|
||||
CS_CZ = 12
|
||||
CY_GB = 13
|
||||
DA_DK = 14
|
||||
DE_AT = 15
|
||||
DE_CH = 16
|
||||
DE_DE = 17
|
||||
EL_GR = 18
|
||||
EN_AU = 19
|
||||
EN_CA = 20
|
||||
EN_GB = 21
|
||||
EN_NZ = 22
|
||||
EN_PT = 23
|
||||
EN_UD = 24
|
||||
EN_US = 25
|
||||
ENP = 26
|
||||
ENWS = 27
|
||||
EO_UY = 28
|
||||
ES_AR = 29
|
||||
ES_CL = 30
|
||||
ES_EC = 31
|
||||
ES_ES = 32
|
||||
ES_MX = 33
|
||||
ES_UY = 34
|
||||
ES_VE = 35
|
||||
ESAN = 36
|
||||
ET_EE = 37
|
||||
EU_ES = 38
|
||||
FA_IR = 39
|
||||
FI_FI = 40
|
||||
FIL_PH = 41
|
||||
FO_FO = 42
|
||||
FR_CA = 43
|
||||
FR_FR = 44
|
||||
FRA_DE = 45
|
||||
FUR_IT = 46
|
||||
FY_NL = 47
|
||||
GA_IE = 48
|
||||
GD_GB = 49
|
||||
GL_ES = 50
|
||||
HAW_US = 51
|
||||
HE_IL = 52
|
||||
HI_IN = 53
|
||||
HR_HR = 54
|
||||
HU_HU = 55
|
||||
HY_AM = 56
|
||||
ID_ID = 57
|
||||
IG_NG = 58
|
||||
IO_EN = 59
|
||||
IS_IS = 60
|
||||
ISV = 61
|
||||
IT_IT = 62
|
||||
JA_JP = 63
|
||||
JBO_EN = 64
|
||||
KA_GE = 65
|
||||
KK_KZ = 66
|
||||
KN_IN = 67
|
||||
KO_KR = 68
|
||||
KSH = 69
|
||||
KW_GB = 70
|
||||
LA_LA = 71
|
||||
LB_LU = 72
|
||||
LI_LI = 73
|
||||
LMO = 74
|
||||
LO_LA = 75
|
||||
LOL_US = 76
|
||||
LT_LT = 77
|
||||
LV_LV = 78
|
||||
LZH = 79
|
||||
MK_MK = 80
|
||||
MN_MN = 81
|
||||
MS_MY = 82
|
||||
MT_MT = 83
|
||||
NAH = 84
|
||||
NDS_DE = 85
|
||||
NL_BE = 86
|
||||
NL_NL = 87
|
||||
NN_NO = 88
|
||||
NO_NO = 89
|
||||
OC_FR = 90
|
||||
OVD = 91
|
||||
PL_PL = 92
|
||||
PT_BR = 93
|
||||
PT_PT = 94
|
||||
QYA_AA = 95
|
||||
RO_RO = 96
|
||||
RPR = 97
|
||||
RU_RU = 98
|
||||
RY_UA = 99
|
||||
SAH_SAH = 100
|
||||
SE_NO = 101
|
||||
SK_SK = 102
|
||||
SL_SI = 103
|
||||
SO_SO = 104
|
||||
SQ_AL = 105
|
||||
SR_CS = 106
|
||||
SR_SP = 107
|
||||
SV_SE = 108
|
||||
SXU = 109
|
||||
SZL = 110
|
||||
TA_IN = 111
|
||||
TH_TH = 112
|
||||
TL_PH = 113
|
||||
TLH_AA = 114
|
||||
TOK = 115
|
||||
TR_TR = 116
|
||||
TT_RU = 117
|
||||
UK_UA = 118
|
||||
VAL_ES = 119
|
||||
VEC_IT = 120
|
||||
VI_VN = 121
|
||||
YI_DE = 122
|
||||
YO_NG = 123
|
||||
ZH_CN = 124
|
||||
ZH_HK = 125
|
||||
ZH_TW = 126
|
||||
ZLM_ARAB = 127
|
||||
|
||||
|
||||
70
src/pumpkin_api/wit_files/wit_world/imports/context.py
Normal file
70
src/pumpkin_api/wit_files/wit_world/imports/context.py
Normal file
@ -0,0 +1,70 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
The core context provided to a plugin during initialization and event handling.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import permission
|
||||
from ..imports import event
|
||||
from ..imports import server
|
||||
from ..imports import command
|
||||
|
||||
class Context:
|
||||
"""
|
||||
A contextual handle for plugin-related operations.
|
||||
"""
|
||||
|
||||
def register_event(self, handler_id: int, event_type: event.EventType, event_priority: event.EventPriority, blocking: bool) -> None:
|
||||
"""
|
||||
Registers a handler for a specific event.
|
||||
|
||||
* `handler-id`: Unique ID for the event handler.
|
||||
* `event-type`: The type of event to listen for.
|
||||
* `event-priority`: When this handler should be called relative to others.
|
||||
* `blocking`: Whether the event should wait for this handler to finish.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def register_command(self, command: command.Command, permission: str) -> None:
|
||||
"""
|
||||
Registers a new command.
|
||||
|
||||
* `command`: The command definition.
|
||||
* `permission`: The required permission node to execute this command.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def register_permission(self, permission: permission.Permission) -> None:
|
||||
"""
|
||||
Registers a permission node with the server.
|
||||
|
||||
Raises: `componentize_py_types.Err(wit_world.imports.str)`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_data_folder(self) -> str:
|
||||
"""
|
||||
Returns the path to the plugin's private data folder.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_server(self) -> server.Server:
|
||||
"""
|
||||
Returns the global server instance.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
84
src/pumpkin_api/wit_files/wit_world/imports/entity.py
Normal file
84
src/pumpkin_api/wit_files/wit_world/imports/entity.py
Normal file
@ -0,0 +1,84 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class BlockEntity:
|
||||
|
||||
def resource_location(self) -> str:
|
||||
raise NotImplementedError
|
||||
def get_position(self) -> Tuple[int, int, int]:
|
||||
raise NotImplementedError
|
||||
def get_id(self) -> int:
|
||||
raise NotImplementedError
|
||||
def is_dirty(self) -> bool:
|
||||
"""
|
||||
write-nbt: func(nbt: nbt-compound);
|
||||
from-nbt: func(nbt: nbt-compound, position: block-position) -> entity;
|
||||
tick: func(world: simple-world);
|
||||
write-internal: func(nbt: nbt-compound);
|
||||
chunk-data-nbt: func() -> option<nbt-compound;
|
||||
get-inventory: func() -> option<inventory>;
|
||||
set-block-state: func(block-state: block-state-id);
|
||||
on-block-replaced: func(world: simple-world, position: block-position);
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def clear_dirty(self) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class CommandBlockEntity:
|
||||
|
||||
def get_block_entity(self) -> BlockEntity:
|
||||
raise NotImplementedError
|
||||
def last_output(self) -> str:
|
||||
raise NotImplementedError
|
||||
def track_output(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def success_count(self) -> int:
|
||||
raise NotImplementedError
|
||||
def command(self) -> str:
|
||||
raise NotImplementedError
|
||||
def auto(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def condition_met(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def powered(self) -> bool:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Entity_CommandBlockEntity:
|
||||
value: CommandBlockEntity
|
||||
|
||||
|
||||
Entity = Union[Entity_CommandBlockEntity]
|
||||
|
||||
|
||||
|
||||
434
src/pumpkin_api/wit_files/wit_world/imports/event.py
Normal file
434
src/pumpkin_api/wit_files/wit_world/imports/event.py
Normal file
@ -0,0 +1,434 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import text
|
||||
from ..imports import world
|
||||
from ..imports import player
|
||||
|
||||
class EventPriority(Enum):
|
||||
HIGHEST = 0
|
||||
HIGH = 1
|
||||
NORMAL = 2
|
||||
LOW = 3
|
||||
LOWEST = 4
|
||||
|
||||
@dataclass
|
||||
class PlayerJoinEventData:
|
||||
player: player.Player
|
||||
join_message: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerLeaveEventData:
|
||||
player: player.Player
|
||||
leave_message: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerLoginEventData:
|
||||
player: player.Player
|
||||
kick_message: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerChatEventData:
|
||||
player: player.Player
|
||||
message: str
|
||||
recipients: List[player.Player]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerCommandSendEventData:
|
||||
player: player.Player
|
||||
command: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerPermissionCheckEventData:
|
||||
player: player.Player
|
||||
permission: str
|
||||
permission_result: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerMoveEventData:
|
||||
player: player.Player
|
||||
from_position: Tuple[float, float, float]
|
||||
to_position: Tuple[float, float, float]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerTeleportEventData:
|
||||
player: player.Player
|
||||
from_position: Tuple[float, float, float]
|
||||
to_position: Tuple[float, float, float]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerChangeWorldEventData:
|
||||
player: player.Player
|
||||
previous_world: world.World
|
||||
new_world: world.World
|
||||
position: Tuple[float, float, float]
|
||||
yaw: float
|
||||
pitch: float
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerExpChangeEventData:
|
||||
player: player.Player
|
||||
amount: int
|
||||
|
||||
@dataclass
|
||||
class PlayerItemHeldEventData:
|
||||
player: player.Player
|
||||
previous_slot: int
|
||||
new_slot: int
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerChangedMainHandEventData:
|
||||
player: player.Player
|
||||
main_hand: common.Hand
|
||||
|
||||
@dataclass
|
||||
class PlayerGamemodeChangeEventData:
|
||||
player: player.Player
|
||||
previous_gamemode: common.GameMode
|
||||
new_gamemode: common.GameMode
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerCustomPayloadEventData:
|
||||
player: player.Player
|
||||
channel: str
|
||||
data: bytes
|
||||
|
||||
class PlayerFishState(Enum):
|
||||
FISHING = 0
|
||||
CAUGHT_FISH = 1
|
||||
CAUGHT_ENTITY = 2
|
||||
IN_GROUND = 3
|
||||
FAILED_ATTEMPT = 4
|
||||
REEL_IN = 5
|
||||
BITE = 6
|
||||
|
||||
@dataclass
|
||||
class PlayerFishEventData:
|
||||
player: player.Player
|
||||
caught_uuid: Optional[str]
|
||||
caught_type: str
|
||||
hook_uuid: str
|
||||
state: PlayerFishState
|
||||
hand: common.Hand
|
||||
exp_to_drop: int
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerEggThrowEventData:
|
||||
player: player.Player
|
||||
egg_uuid: str
|
||||
hatching: bool
|
||||
num_hatches: int
|
||||
hatching_type: str
|
||||
cancelled: bool
|
||||
|
||||
class EntityInteractionAction(Enum):
|
||||
INTERACT = 0
|
||||
ATTACK = 1
|
||||
INTERACT_AT = 2
|
||||
|
||||
class InteractAction(Enum):
|
||||
LEFT_CLICK_BLOCK = 0
|
||||
LEFT_CLICK_AIR = 1
|
||||
RIGHT_CLICK_AIR = 2
|
||||
RIGHT_CLICK_BLOCK = 3
|
||||
|
||||
@dataclass
|
||||
class PlayerInteractEventData:
|
||||
player: player.Player
|
||||
action: InteractAction
|
||||
clicked_pos: Optional[Tuple[int, int, int]]
|
||||
item: common.ItemStack
|
||||
block: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerToggleSneakEventData:
|
||||
player: player.Player
|
||||
is_sneaking: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerToggleSprintEventData:
|
||||
player: player.Player
|
||||
is_sprinting: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class PlayerInteractUnknownEntityEventData:
|
||||
player: player.Player
|
||||
entity_id: int
|
||||
action: EntityInteractionAction
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockRedstoneEventData:
|
||||
target_world: world.World
|
||||
state_id: int
|
||||
block_position: Tuple[int, int, int]
|
||||
old_current: int
|
||||
new_current: int
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockBreakEventData:
|
||||
player: Optional[player.Player]
|
||||
block: str
|
||||
block_position: Tuple[int, int, int]
|
||||
exp: int
|
||||
should_drop: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockBurnEventData:
|
||||
igniting_block: str
|
||||
block: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockCanBuildEventData:
|
||||
block_to_build: str
|
||||
buildable: bool
|
||||
player: player.Player
|
||||
block: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockGrowEventData:
|
||||
target_world: world.World
|
||||
old_block: str
|
||||
old_state_id: int
|
||||
new_block: str
|
||||
new_state_id: int
|
||||
block_position: Tuple[int, int, int]
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class BlockPlaceEventData:
|
||||
player: player.Player
|
||||
block_placed: str
|
||||
block_placed_against: str
|
||||
block_position: Tuple[int, int, int]
|
||||
can_build: bool
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class ServerCommandEventData:
|
||||
command: str
|
||||
cancelled: bool
|
||||
|
||||
@dataclass
|
||||
class SpawnChangeEventData:
|
||||
target_world: world.World
|
||||
previous_position: Tuple[int, int, int]
|
||||
previous_yaw: float
|
||||
previous_pitch: float
|
||||
new_position: Tuple[int, int, int]
|
||||
new_yaw: float
|
||||
new_pitch: float
|
||||
|
||||
@dataclass
|
||||
class ServerBroadcastEventData:
|
||||
message: text.TextComponent
|
||||
sender: text.TextComponent
|
||||
cancelled: bool
|
||||
|
||||
class EventType(Enum):
|
||||
PLAYER_JOIN_EVENT = 0
|
||||
PLAYER_LEAVE_EVENT = 1
|
||||
PLAYER_LOGIN_EVENT = 2
|
||||
PLAYER_CHAT_EVENT = 3
|
||||
PLAYER_COMMAND_SEND_EVENT = 4
|
||||
PLAYER_PERMISSION_CHECK_EVENT = 5
|
||||
PLAYER_MOVE_EVENT = 6
|
||||
PLAYER_TELEPORT_EVENT = 7
|
||||
PLAYER_CHANGE_WORLD_EVENT = 8
|
||||
PLAYER_EXP_CHANGE_EVENT = 9
|
||||
PLAYER_ITEM_HELD_EVENT = 10
|
||||
PLAYER_CHANGED_MAIN_HAND_EVENT = 11
|
||||
PLAYER_GAMEMODE_CHANGE_EVENT = 12
|
||||
PLAYER_CUSTOM_PAYLOAD_EVENT = 13
|
||||
PLAYER_FISH_EVENT = 14
|
||||
PLAYER_EGG_THROW_EVENT = 15
|
||||
PLAYER_INTERACT_UNKNOWN_ENTITY_EVENT = 16
|
||||
PLAYER_INTERACT_EVENT = 17
|
||||
PLAYER_TOGGLE_SNEAK_EVENT = 18
|
||||
PLAYER_TOGGLE_SPRINT_EVENT = 19
|
||||
BLOCK_REDSTONE_EVENT = 20
|
||||
BLOCK_BREAK_EVENT = 21
|
||||
BLOCK_BURN_EVENT = 22
|
||||
BLOCK_CAN_BUILD_EVENT = 23
|
||||
BLOCK_GROW_EVENT = 24
|
||||
BLOCK_PLACE_EVENT = 25
|
||||
SERVER_COMMAND_EVENT = 26
|
||||
SPAWN_CHANGE_EVENT = 27
|
||||
SERVER_BROADCAST_EVENT = 28
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerJoinEvent:
|
||||
value: PlayerJoinEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerLeaveEvent:
|
||||
value: PlayerLeaveEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerLoginEvent:
|
||||
value: PlayerLoginEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerChatEvent:
|
||||
value: PlayerChatEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerCommandSendEvent:
|
||||
value: PlayerCommandSendEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerPermissionCheckEvent:
|
||||
value: PlayerPermissionCheckEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerMoveEvent:
|
||||
value: PlayerMoveEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerTeleportEvent:
|
||||
value: PlayerTeleportEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerChangeWorldEvent:
|
||||
value: PlayerChangeWorldEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerExpChangeEvent:
|
||||
value: PlayerExpChangeEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerItemHeldEvent:
|
||||
value: PlayerItemHeldEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerChangedMainHandEvent:
|
||||
value: PlayerChangedMainHandEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerGamemodeChangeEvent:
|
||||
value: PlayerGamemodeChangeEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerCustomPayloadEvent:
|
||||
value: PlayerCustomPayloadEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerFishEvent:
|
||||
value: PlayerFishEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerEggThrowEvent:
|
||||
value: PlayerEggThrowEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerInteractUnknownEntityEvent:
|
||||
value: PlayerInteractUnknownEntityEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerInteractEvent:
|
||||
value: PlayerInteractEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerToggleSneakEvent:
|
||||
value: PlayerToggleSneakEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_PlayerToggleSprintEvent:
|
||||
value: PlayerToggleSprintEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockRedstoneEvent:
|
||||
value: BlockRedstoneEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockBreakEvent:
|
||||
value: BlockBreakEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockBurnEvent:
|
||||
value: BlockBurnEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockCanBuildEvent:
|
||||
value: BlockCanBuildEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockGrowEvent:
|
||||
value: BlockGrowEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_BlockPlaceEvent:
|
||||
value: BlockPlaceEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_ServerCommandEvent:
|
||||
value: ServerCommandEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_SpawnChangeEvent:
|
||||
value: SpawnChangeEventData
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event_ServerBroadcastEvent:
|
||||
value: ServerBroadcastEventData
|
||||
|
||||
|
||||
Event = Union[Event_PlayerJoinEvent, Event_PlayerLeaveEvent, Event_PlayerLoginEvent, Event_PlayerChatEvent, Event_PlayerCommandSendEvent, Event_PlayerPermissionCheckEvent, Event_PlayerMoveEvent, Event_PlayerTeleportEvent, Event_PlayerChangeWorldEvent, Event_PlayerExpChangeEvent, Event_PlayerItemHeldEvent, Event_PlayerChangedMainHandEvent, Event_PlayerGamemodeChangeEvent, Event_PlayerCustomPayloadEvent, Event_PlayerFishEvent, Event_PlayerEggThrowEvent, Event_PlayerInteractUnknownEntityEvent, Event_PlayerInteractEvent, Event_PlayerToggleSneakEvent, Event_PlayerToggleSprintEvent, Event_BlockRedstoneEvent, Event_BlockBreakEvent, Event_BlockBurnEvent, Event_BlockCanBuildEvent, Event_BlockGrowEvent, Event_BlockPlaceEvent, Event_ServerCommandEvent, Event_SpawnChangeEvent, Event_ServerBroadcastEvent]
|
||||
|
||||
|
||||
|
||||
61
src/pumpkin_api/wit_files/wit_world/imports/gui.py
Normal file
61
src/pumpkin_api/wit_files/wit_world/imports/gui.py
Normal file
@ -0,0 +1,61 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import text
|
||||
|
||||
class GuiType(Enum):
|
||||
GENERIC_9X1 = 0
|
||||
GENERIC_9X2 = 1
|
||||
GENERIC_9X3 = 2
|
||||
GENERIC_9X4 = 3
|
||||
GENERIC_9X5 = 4
|
||||
GENERIC_9X6 = 5
|
||||
GENERIC_3X3 = 6
|
||||
CRAFTER_3X3 = 7
|
||||
ANVIL = 8
|
||||
BEACON = 9
|
||||
BLAST_FURNACE = 10
|
||||
BREWING_STAND = 11
|
||||
CRAFTING = 12
|
||||
ENCHANTMENT = 13
|
||||
FURNACE = 14
|
||||
GRINDSTONE = 15
|
||||
HOPPER = 16
|
||||
LECTERN = 17
|
||||
LOOM = 18
|
||||
MERCHANT = 19
|
||||
SHULKER_BOX = 20
|
||||
SMITHING = 21
|
||||
SMOKER = 22
|
||||
CARTOGRAPHY_TABLE = 23
|
||||
STONECUTTER = 24
|
||||
|
||||
class Gui:
|
||||
|
||||
def __init__(self, type: GuiType, title: text.TextComponent) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_item(self, slot: int, item: common.ItemStack) -> None:
|
||||
raise NotImplementedError
|
||||
def get_item(self, slot: int) -> Optional[common.ItemStack]:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
35
src/pumpkin_api/wit_files/wit_world/imports/i18n.py
Normal file
35
src/pumpkin_api/wit_files/wit_world/imports/i18n.py
Normal file
@ -0,0 +1,35 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
|
||||
|
||||
def translate(key: str, locale: common.Locale) -> str:
|
||||
"""
|
||||
Retrieves a translated string from the host.
|
||||
|
||||
# Arguments
|
||||
* `key`: The namespaced translation key (e.g. `pumpkin:my_key`).
|
||||
* `locale`: The target locale.
|
||||
|
||||
# Returns
|
||||
The localized string, falling back to English or the key itself.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def load_translations(namespace: str, json: str, locale: common.Locale) -> None:
|
||||
"""
|
||||
Loads custom translations from a JSON string.
|
||||
|
||||
# Arguments
|
||||
* `namespace`: The namespace to associate these keys with.
|
||||
* `json`: A JSON string containing a flat map of translations.
|
||||
* `locale`: The target locale for these translations.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
30
src/pumpkin_api/wit_files/wit_world/imports/logging.py
Normal file
30
src/pumpkin_api/wit_files/wit_world/imports/logging.py
Normal file
@ -0,0 +1,30 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class Level(Enum):
|
||||
TRACE = 0
|
||||
DEBUG = 1
|
||||
INFO = 2
|
||||
WARN = 3
|
||||
ERROR = 4
|
||||
|
||||
|
||||
def log(level: Level, message: str) -> None:
|
||||
"""
|
||||
log any general purpose message
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def log_tracing(event: bytes) -> None:
|
||||
"""
|
||||
This function is meant to be used by the tracing crate.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
71
src/pumpkin_api/wit_files/wit_world/imports/permission.py
Normal file
71
src/pumpkin_api/wit_files/wit_world/imports/permission.py
Normal file
@ -0,0 +1,71 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
class PermissionLevel(Enum):
|
||||
"""
|
||||
Represents the player's permission level
|
||||
|
||||
Permission levels determine the player's access to commands and server operations.
|
||||
Each numeric level corresponds to a specific role:
|
||||
- `Zero`: `normal`: Player can use basic commands.
|
||||
- `One`: `moderator`: Player can bypass spawn protection.
|
||||
- `Two`: `gamemaster`: Player or executor can use more commands and player can use command blocks.
|
||||
- `Three`: `admin`: Player or executor can use commands related to multiplayer management.
|
||||
- `Four`: `owner`: Player or executor can use all of the commands, including commands related to server management.
|
||||
"""
|
||||
ZERO = 0
|
||||
ONE = 1
|
||||
TWO = 2
|
||||
THREE = 3
|
||||
FOUR = 4
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionDefault_Deny:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionDefault_Allow:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionDefault_Op:
|
||||
value: PermissionLevel
|
||||
|
||||
|
||||
PermissionDefault = Union[PermissionDefault_Deny, PermissionDefault_Allow, PermissionDefault_Op]
|
||||
"""
|
||||
Describes the default behavior for permissions
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class PermissionChild:
|
||||
"""
|
||||
A child permission entry
|
||||
"""
|
||||
node: str
|
||||
value: bool
|
||||
|
||||
@dataclass
|
||||
class Permission:
|
||||
"""
|
||||
Defines a permission node in the system
|
||||
"""
|
||||
node: str
|
||||
description: str
|
||||
default: PermissionDefault
|
||||
children: List[PermissionChild]
|
||||
|
||||
|
||||
350
src/pumpkin_api/wit_files/wit_world/imports/player.py
Normal file
350
src/pumpkin_api/wit_files/wit_world/imports/player.py
Normal file
@ -0,0 +1,350 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Represents a player connected to the Minecraft server.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import permission
|
||||
from ..imports import text
|
||||
from ..imports import gui
|
||||
from ..imports import world
|
||||
|
||||
@dataclass
|
||||
class PlayerAbilities:
|
||||
"""
|
||||
Various abilities a player can have.
|
||||
"""
|
||||
invulnerable: bool
|
||||
flying: bool
|
||||
allow_flying: bool
|
||||
creative: bool
|
||||
allow_modify_world: bool
|
||||
fly_speed: float
|
||||
walk_speed: float
|
||||
|
||||
class Player:
|
||||
"""
|
||||
A handle to a player on the server.
|
||||
"""
|
||||
|
||||
def get_id(self) -> str:
|
||||
"""
|
||||
Returns the player's unique UUID as a string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Returns the player's username.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_position(self) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Basic state
|
||||
Returns the player's current position in the world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_yaw(self) -> float:
|
||||
"""
|
||||
Returns the player's current yaw (horizontal rotation).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_pitch(self) -> float:
|
||||
"""
|
||||
Returns the player's current pitch (vertical rotation).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_world(self) -> world.World:
|
||||
"""
|
||||
Returns the world the player is currently in.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_gamemode(self) -> common.GameMode:
|
||||
"""
|
||||
Returns the player's current game mode.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_gamemode(self, mode: common.GameMode) -> bool:
|
||||
"""
|
||||
Changes the player's game mode. Returns true if successful.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_locale(self) -> str:
|
||||
"""
|
||||
Returns the player's locale (e.g., "en_us").
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_ping(self) -> int:
|
||||
"""
|
||||
Returns the player's current ping in milliseconds.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_permission_level(self) -> permission.PermissionLevel:
|
||||
"""
|
||||
Permissions & metadata
|
||||
Returns the player's permission level (0-4).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_permission_level(self, level: permission.PermissionLevel) -> None:
|
||||
"""
|
||||
Sets the player's permission level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def has_permission(self, node: str) -> bool:
|
||||
"""
|
||||
Checks if the player has a specific permission node.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_display_name(self) -> text.TextComponent:
|
||||
"""
|
||||
Returns the player's display name, which may include formatting.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def send_system_message(self, text: text.TextComponent, overlay: bool) -> None:
|
||||
"""
|
||||
Messaging & titles
|
||||
Sends a system message to the player's chat.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def show_title(self, text: text.TextComponent) -> None:
|
||||
"""
|
||||
Shows a large title on the player's screen.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def show_subtitle(self, text: text.TextComponent) -> None:
|
||||
"""
|
||||
Shows a smaller subtitle on the player's screen.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def show_actionbar(self, text: text.TextComponent) -> None:
|
||||
"""
|
||||
Shows a message in the action bar area.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def send_title_animation(self, fade_in: int, stay: int, fade_out: int) -> None:
|
||||
"""
|
||||
Sets the fade-in, stay, and fade-out times for titles.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def teleport(self, position: Tuple[float, float, float], yaw: Optional[float], pitch: Optional[float], world: world.World) -> None:
|
||||
"""
|
||||
Teleport & kick
|
||||
Teleports the player to a position in a world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def teleport_world(self, world_ref: world.World, position: Tuple[float, float, float], yaw: Optional[float], pitch: Optional[float]) -> None:
|
||||
"""
|
||||
Teleports the player to another world at a specific position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def kick(self, message: text.TextComponent) -> None:
|
||||
"""
|
||||
Kicks the player from the server with the specified reason.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def respawn(self) -> None:
|
||||
"""
|
||||
Forces the player to respawn.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def open_gui(self, gui_ref: gui.Gui) -> None:
|
||||
"""
|
||||
Opens a GUI for the player.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def ban(self, reason: Optional[text.TextComponent]) -> None:
|
||||
"""
|
||||
Bans the player with an optional reason.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def ban_ip(self, reason: Optional[text.TextComponent]) -> None:
|
||||
"""
|
||||
Bans the player's IP address with an optional reason.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_selected_slot(self) -> int:
|
||||
"""
|
||||
Inventory
|
||||
Returns the index of the currently selected hotbar slot (0-8).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_item_in_hand(self, hand: common.Hand) -> Optional[common.ItemStack]:
|
||||
"""
|
||||
Returns the item currently in the specified hand.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_inventory_item(self, slot: int) -> Optional[common.ItemStack]:
|
||||
"""
|
||||
Returns the item in the specified inventory slot.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_health(self) -> float:
|
||||
"""
|
||||
Status
|
||||
Returns the player's current health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_health(self, health: float) -> None:
|
||||
"""
|
||||
Sets the player's current health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_max_health(self) -> float:
|
||||
"""
|
||||
Returns the player's maximum health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_max_health(self, max_health: float) -> None:
|
||||
"""
|
||||
Sets the player's maximum health.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_food_level(self) -> int:
|
||||
"""
|
||||
Returns the player's food level (0-20).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_food_level(self, food_level: int) -> None:
|
||||
"""
|
||||
Sets the player's food level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_saturation(self) -> float:
|
||||
"""
|
||||
Returns the player's food saturation level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_saturation(self, saturation: float) -> None:
|
||||
"""
|
||||
Sets the player's food saturation level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_exhaustion(self) -> float:
|
||||
"""
|
||||
Returns the player's food exhaustion level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_exhaustion(self, exhaustion: float) -> None:
|
||||
"""
|
||||
Sets the player's food exhaustion level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_absorption(self) -> float:
|
||||
"""
|
||||
Returns the player's current absorption amount.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_absorption(self, absorption: float) -> None:
|
||||
"""
|
||||
Sets the player's current absorption amount.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_experience_level(self) -> int:
|
||||
"""
|
||||
Returns the player's total experience level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_experience_progress(self) -> float:
|
||||
"""
|
||||
Returns the player's progress toward the next level (0.0 to 1.0).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_experience_points(self) -> int:
|
||||
"""
|
||||
Returns the total experience points the player has.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_experience_level(self, level: int) -> None:
|
||||
"""
|
||||
Sets the player's total experience level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_experience_progress(self, progress: float) -> None:
|
||||
"""
|
||||
Sets the player's progress toward the next level.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_experience_points(self, points: int) -> None:
|
||||
"""
|
||||
Sets the player's total experience points.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def add_experience_levels(self, levels: int) -> None:
|
||||
"""
|
||||
Adds experience levels to the player.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def add_experience_points(self, points: int) -> None:
|
||||
"""
|
||||
Adds experience points to the player.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_sneaking(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently sneaking.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_sneaking(self, sneaking: bool) -> None:
|
||||
"""
|
||||
Sets whether the player is currently sneaking.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_sprinting(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently sprinting.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_sprinting(self, sprinting: bool) -> None:
|
||||
"""
|
||||
Sets whether the player is currently sprinting.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_on_ground(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently on the ground.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_flying(self) -> bool:
|
||||
"""
|
||||
Returns whether the player is currently flying.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_flying(self, flying: bool) -> None:
|
||||
"""
|
||||
Sets whether the player should be flying.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_abilities(self) -> PlayerAbilities:
|
||||
"""
|
||||
Returns the player's current abilities.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_abilities(self, abilities: PlayerAbilities) -> None:
|
||||
"""
|
||||
Updates the player's abilities.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_ip(self) -> str:
|
||||
"""
|
||||
Returns the player's IP address.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
44
src/pumpkin_api/wit_files/wit_world/imports/scheduler.py
Normal file
44
src/pumpkin_api/wit_files/wit_world/imports/scheduler.py
Normal file
@ -0,0 +1,44 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
"""
|
||||
Provides functionality to schedule tasks to be executed later on the server.
|
||||
"""
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
|
||||
|
||||
|
||||
def schedule_delayed_task(handler_id: int, delay_ticks: int) -> int:
|
||||
"""
|
||||
Schedules a task to be executed once after the specified number of ticks.
|
||||
|
||||
* `handler-id`: The unique ID of the handler to call when the task executes.
|
||||
* `delay-ticks`: The number of game ticks to wait before execution (20 ticks = 1 second).
|
||||
|
||||
Returns a unique task ID that can be used to cancel the task.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def schedule_repeating_task(handler_id: int, delay_ticks: int, period_ticks: int) -> int:
|
||||
"""
|
||||
Schedules a task to be executed repeatedly.
|
||||
|
||||
* `handler-id`: The unique ID of the handler to call when the task executes.
|
||||
* `delay-ticks`: The number of game ticks to wait before the first execution.
|
||||
* `period-ticks`: The number of game ticks between subsequent executions.
|
||||
|
||||
Returns a unique task ID that can be used to cancel the task.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def cancel_task(task_id: int) -> None:
|
||||
"""
|
||||
Cancels a scheduled task if it hasn't finished yet.
|
||||
|
||||
* `task-id`: The ID of the task to cancel.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
95
src/pumpkin_api/wit_files/wit_world/imports/scoreboard.py
Normal file
95
src/pumpkin_api/wit_files/wit_world/imports/scoreboard.py
Normal file
@ -0,0 +1,95 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
from ..imports import text
|
||||
|
||||
class RenderType(Enum):
|
||||
INTEGER = 0
|
||||
HEARTS = 1
|
||||
|
||||
class DisplaySlot(Enum):
|
||||
PLAYER_LIST = 0
|
||||
SIDEBAR = 1
|
||||
BELOW_NAME = 2
|
||||
SIDEBAR_TEAM_BLACK = 3
|
||||
SIDEBAR_TEAM_DARK_BLUE = 4
|
||||
SIDEBAR_TEAM_DARK_GREEN = 5
|
||||
SIDEBAR_TEAM_DARK_AQUA = 6
|
||||
SIDEBAR_TEAM_DARK_RED = 7
|
||||
SIDEBAR_TEAM_DARK_PURPLE = 8
|
||||
SIDEBAR_TEAM_GOLD = 9
|
||||
SIDEBAR_TEAM_GRAY = 10
|
||||
SIDEBAR_TEAM_DARK_GRAY = 11
|
||||
SIDEBAR_TEAM_BLUE = 12
|
||||
SIDEBAR_TEAM_GREEN = 13
|
||||
SIDEBAR_TEAM_AQUA = 14
|
||||
SIDEBAR_TEAM_RED = 15
|
||||
SIDEBAR_TEAM_LIGHT_PURPLE = 16
|
||||
SIDEBAR_TEAM_YELLOW = 17
|
||||
SIDEBAR_TEAM_WHITE = 18
|
||||
|
||||
class NametagVisibility(Enum):
|
||||
ALWAYS = 0
|
||||
NEVER = 1
|
||||
HIDE_FOR_OTHER_TEAMS = 2
|
||||
HIDE_FOR_OWN_TEAM = 3
|
||||
|
||||
class CollisionRule(Enum):
|
||||
ALWAYS = 0
|
||||
NEVER = 1
|
||||
PUSH_OTHER_TEAMS = 2
|
||||
PUSH_OWN_TEAM = 3
|
||||
|
||||
@dataclass
|
||||
class TeamSettings:
|
||||
display_name: text.TextComponent
|
||||
friendly_fire: bool
|
||||
see_friendly_invisibles: bool
|
||||
nametag_visibility: NametagVisibility
|
||||
collision_rule: CollisionRule
|
||||
color: common.NamedColor
|
||||
prefix: text.TextComponent
|
||||
suffix: text.TextComponent
|
||||
|
||||
class Scoreboard:
|
||||
|
||||
def add_objective(self, name: str, display_name: text.TextComponent, render_type: RenderType) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_objective(self, name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def set_display_slot(self, slot: DisplaySlot, objective_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def update_score(self, entity_name: str, objective_name: str, value: int) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_score(self, entity_name: str, objective_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def create_team(self, name: str, settings: TeamSettings) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_team(self, name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def update_team(self, name: str, settings: TeamSettings) -> None:
|
||||
raise NotImplementedError
|
||||
def add_player_to_team(self, team_name: str, player_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def remove_player_from_team(self, team_name: str, player_name: str) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
75
src/pumpkin_api/wit_files/wit_world/imports/server.py
Normal file
75
src/pumpkin_api/wit_files/wit_world/imports/server.py
Normal file
@ -0,0 +1,75 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import player
|
||||
|
||||
class Difficulty(Enum):
|
||||
"""
|
||||
Represents the difficulty setting of a Minecraft server.
|
||||
"""
|
||||
PEACEFUL = 0
|
||||
EASY = 1
|
||||
NORMAL = 2
|
||||
HARD = 3
|
||||
|
||||
class Server:
|
||||
"""
|
||||
Represents the global server instance.
|
||||
"""
|
||||
|
||||
def get_difficulty(self) -> Difficulty:
|
||||
"""
|
||||
Returns the current difficulty level of the server.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_player_count(self) -> int:
|
||||
"""
|
||||
Returns the total number of players currently connected to the server.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_mspt(self) -> float:
|
||||
"""
|
||||
Returns the rolling average Milliseconds Per Tick (MSPT).
|
||||
A value below 50.0 is required for a stable 20 TPS.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_tps(self) -> float:
|
||||
"""
|
||||
Returns the effective Ticks Per Second (TPS).
|
||||
Ideal value is 20.0.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_all_players(self) -> List[player.Player]:
|
||||
"""
|
||||
Returns a list of all online players across all worlds.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_player_by_name(self, name: str) -> Optional[player.Player]:
|
||||
"""
|
||||
Searches for a player by their exact name.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_player_by_uuid(self, id: str) -> Optional[player.Player]:
|
||||
"""
|
||||
Searches for a player by their UUID string.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
89
src/pumpkin_api/wit_files/wit_world/imports/text.py
Normal file
89
src/pumpkin_api/wit_files/wit_world/imports/text.py
Normal file
@ -0,0 +1,89 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import common
|
||||
|
||||
class TextComponent:
|
||||
|
||||
@classmethod
|
||||
def text(cls, plain: str) -> Self:
|
||||
raise NotImplementedError
|
||||
@classmethod
|
||||
def translate(cls, key: str, with_: List[Self]) -> Self:
|
||||
raise NotImplementedError
|
||||
def add_child(self, child: Self) -> None:
|
||||
raise NotImplementedError
|
||||
def add_text(self, text: str) -> None:
|
||||
raise NotImplementedError
|
||||
def get_text(self) -> str:
|
||||
raise NotImplementedError
|
||||
def encode(self) -> bytes:
|
||||
raise NotImplementedError
|
||||
def color_named(self, color: common.NamedColor) -> None:
|
||||
"""
|
||||
Style
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def color_rgb(self, color: common.RgbColor) -> None:
|
||||
raise NotImplementedError
|
||||
def bold(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def italic(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def underlined(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def strikethrough(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def obfuscated(self, value: bool) -> None:
|
||||
raise NotImplementedError
|
||||
def insertion(self, text: str) -> None:
|
||||
"""
|
||||
Text inserted into chat when shift-clicked
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def font(self, font: str) -> None:
|
||||
raise NotImplementedError
|
||||
def shadow_color(self, color: common.ArgbColor) -> None:
|
||||
raise NotImplementedError
|
||||
def click_open_url(self, url: str) -> None:
|
||||
"""
|
||||
Click events
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def click_run_command(self, command: str) -> None:
|
||||
raise NotImplementedError
|
||||
def click_suggest_command(self, command: str) -> None:
|
||||
raise NotImplementedError
|
||||
def click_copy_to_clipboard(self, text: str) -> None:
|
||||
raise NotImplementedError
|
||||
def hover_show_text(self, text: Self) -> None:
|
||||
"""
|
||||
Hover events
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def hover_show_item(self, item: str) -> None:
|
||||
"""
|
||||
Item data as SNBT string
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def hover_show_entity(self, entity_type: str, id: str, name: Optional[Self]) -> None:
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
215
src/pumpkin_api/wit_files/wit_world/imports/world.py
Normal file
215
src/pumpkin_api/wit_files/wit_world/imports/world.py
Normal file
@ -0,0 +1,215 @@
|
||||
# This file is automatically generated by componentize-py
|
||||
# It is not intended for manual editing.
|
||||
from typing import TypeVar, Generic, Union, Optional, Protocol, Tuple, List, Any, Self, Callable
|
||||
from types import TracebackType
|
||||
from enum import Flag, Enum, auto
|
||||
from dataclasses import dataclass
|
||||
from abc import abstractmethod
|
||||
import weakref
|
||||
|
||||
from componentize_py_types import Result, Ok, Err, Some
|
||||
from ..imports import text
|
||||
from ..imports import scoreboard
|
||||
|
||||
class PistonBehavior(Enum):
|
||||
"""
|
||||
Defines how a block reacts when pushed by a piston.
|
||||
"""
|
||||
NORMAL = 0
|
||||
DESTROY = 1
|
||||
BLOCK = 2
|
||||
IGNORE = 3
|
||||
PUSH_ONLY = 4
|
||||
|
||||
class SoundCategory(Enum):
|
||||
"""
|
||||
Categories for sounds to control their volume independently.
|
||||
"""
|
||||
MASTER = 0
|
||||
MUSIC = 1
|
||||
RECORDS = 2
|
||||
WEATHER = 3
|
||||
BLOCKS = 4
|
||||
HOSTILE = 5
|
||||
NEUTRAL = 6
|
||||
PLAYERS = 7
|
||||
AMBIENT = 8
|
||||
VOICE = 9
|
||||
|
||||
class ExplosionInteraction(Enum):
|
||||
"""
|
||||
Defines how an explosion interacts with blocks in the world.
|
||||
"""
|
||||
NONE = 0
|
||||
BLOCK = 1
|
||||
MOB = 2
|
||||
TNT = 3
|
||||
TRIGGER = 4
|
||||
|
||||
class BlockFlags(Flag):
|
||||
"""
|
||||
Flags used to control block updates and notifications.
|
||||
"""
|
||||
NOTIFY_NEIGHBORS = auto()
|
||||
NOTIFY_LISTENERS = auto()
|
||||
FORCE_STATE = auto()
|
||||
SKIP_DROPS = auto()
|
||||
MOVED = auto()
|
||||
SKIP_REDSTONE_WIRE_STATE_REPLACEMENT = auto()
|
||||
SKIP_BLOCK_ENTITY_REPLACED_CALLBACK = auto()
|
||||
SKIP_BLOCK_ADDED_CALLBACK = auto()
|
||||
|
||||
@dataclass
|
||||
class BlockState:
|
||||
"""
|
||||
Detailed information about a block's state.
|
||||
"""
|
||||
id: int
|
||||
luminance: int
|
||||
opacity: int
|
||||
hardness: float
|
||||
is_air: bool
|
||||
is_liquid: bool
|
||||
is_solid: bool
|
||||
is_full_cube: bool
|
||||
piston_behavior: PistonBehavior
|
||||
has_random_ticks: bool
|
||||
|
||||
@dataclass
|
||||
class BlockStateId:
|
||||
"""
|
||||
A simple wrapper for a block state ID.
|
||||
"""
|
||||
id: int
|
||||
|
||||
@dataclass
|
||||
class BlockPos:
|
||||
"""
|
||||
A position in the world grid.
|
||||
"""
|
||||
x: int
|
||||
y: int
|
||||
z: int
|
||||
|
||||
class World:
|
||||
"""
|
||||
Represents a Minecraft world (dimension).
|
||||
"""
|
||||
|
||||
def get_id(self) -> str:
|
||||
"""
|
||||
Returns the unique identifier of this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_block_state_id(self, pos: BlockPos) -> int:
|
||||
"""
|
||||
Gets the block state ID at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_block_state(self, pos: BlockPos) -> BlockState:
|
||||
"""
|
||||
Gets detailed block state information at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_block_state(self, pos: BlockPos, state: int, update_flags: BlockFlags) -> None:
|
||||
"""
|
||||
Sets the block state at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_time_of_day(self) -> int:
|
||||
"""
|
||||
Returns the current time of day in ticks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_time_of_day(self, time: int) -> None:
|
||||
"""
|
||||
Sets the current time of day in ticks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_world_age(self) -> int:
|
||||
"""
|
||||
Returns the total age of the world in ticks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_dimension(self) -> str:
|
||||
"""
|
||||
Returns the dimension type (e.g., "minecraft:overworld").
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_top_block_y(self, x: int, z: int) -> int:
|
||||
"""
|
||||
Gets the highest non-air block Y coordinate at the specified X and Z.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_motion_blocking_height(self, x: int, z: int) -> int:
|
||||
"""
|
||||
Gets the highest motion-blocking block Y coordinate.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_raining(self) -> bool:
|
||||
"""
|
||||
Returns whether it is currently raining or snowing.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_raining(self, raining: bool) -> None:
|
||||
"""
|
||||
Sets whether it should be raining or snowing.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def is_thundering(self) -> bool:
|
||||
"""
|
||||
Returns whether there is currently a thunderstorm.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def set_thundering(self, thundering: bool) -> None:
|
||||
"""
|
||||
Sets whether there should be a thunderstorm.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def broadcast_system_message(self, message: text.TextComponent, overlay: bool) -> None:
|
||||
"""
|
||||
Broadcasts a system message to all players in this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_scoreboard(self) -> scoreboard.Scoreboard:
|
||||
"""
|
||||
Returns the scoreboard associated with this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def play_sound(self, sound: str, category: SoundCategory, pos: Tuple[float, float, float], volume: float, pitch: float) -> None:
|
||||
"""
|
||||
Plays a sound at the specified position for all players in the world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def spawn_particle(self, particle: str, pos: Tuple[float, float, float], offset: Tuple[float, float, float], max_speed: float, count: int) -> None:
|
||||
"""
|
||||
Spawns particles at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def create_explosion(self, pos: Tuple[float, float, float], power: float, create_fire: bool, interaction: ExplosionInteraction) -> None:
|
||||
"""
|
||||
Creates an explosion at the specified position.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_sea_level(self) -> int:
|
||||
"""
|
||||
Returns the sea level of this world.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def get_min_y(self) -> int:
|
||||
"""
|
||||
Returns the minimum Y coordinate (bottom of the world).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
def __enter__(self) -> Self:
|
||||
"""Returns self"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> bool | None:
|
||||
"""
|
||||
Release this resource.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
169
src/pumpkin_api/wit_files/world.wit
Normal file
169
src/pumpkin_api/wit_files/world.wit
Normal file
@ -0,0 +1,169 @@
|
||||
interface %world {
|
||||
use common.{position};
|
||||
use text.{text-component};
|
||||
use scoreboard.{scoreboard};
|
||||
|
||||
/// Defines how a block reacts when pushed by a piston.
|
||||
enum piston-behavior {
|
||||
/// Normal behavior; the block can be pushed and pulled.
|
||||
normal,
|
||||
/// The block is destroyed when pushed.
|
||||
destroy,
|
||||
/// The block cannot be pushed or pulled.
|
||||
block,
|
||||
/// The block is ignored by pistons.
|
||||
ignore,
|
||||
/// The block can only be pushed, not pulled.
|
||||
push-only
|
||||
}
|
||||
|
||||
/// Categories for sounds to control their volume independently.
|
||||
enum sound-category {
|
||||
master,
|
||||
music,
|
||||
records,
|
||||
weather,
|
||||
blocks,
|
||||
hostile,
|
||||
neutral,
|
||||
players,
|
||||
ambient,
|
||||
voice,
|
||||
}
|
||||
|
||||
/// Defines how an explosion interacts with blocks in the world.
|
||||
enum explosion-interaction {
|
||||
/// No interaction with blocks.
|
||||
none,
|
||||
/// Blocks are destroyed and may drop loot.
|
||||
block,
|
||||
/// Interaction typical for mob-caused explosions.
|
||||
mob,
|
||||
/// Interaction typical for TNT explosions.
|
||||
tnt,
|
||||
/// Triggers specific block behaviors.
|
||||
trigger,
|
||||
}
|
||||
|
||||
/// Flags used to control block updates and notifications.
|
||||
flags block-flags {
|
||||
/// Notifies neighbor blocks of the change.
|
||||
notify-neighbors,
|
||||
/// Notifies client listeners of the change.
|
||||
notify-listeners,
|
||||
/// Forces the block state even if it's the same.
|
||||
force-state,
|
||||
/// Skips dropping items when the block is removed.
|
||||
skip-drops,
|
||||
/// Indicates the block was moved (e.g., by a piston).
|
||||
moved,
|
||||
/// Skips state replacement for redstone wires.
|
||||
skip-redstone-wire-state-replacement,
|
||||
/// Skips the callback when a block entity is replaced.
|
||||
skip-block-entity-replaced-callback,
|
||||
/// Skips the callback when a block is added.
|
||||
skip-block-added-callback,
|
||||
}
|
||||
|
||||
/// Detailed information about a block's state.
|
||||
record block-state {
|
||||
/// The internal numerical ID of the block state.
|
||||
id: u16,
|
||||
/// The light level emitted by this block (0-15).
|
||||
luminance: u8,
|
||||
/// How much light this block blocks.
|
||||
opacity: u8,
|
||||
/// The hardness of the block, determining mining speed.
|
||||
hardness: f32,
|
||||
/// Whether this block is considered air.
|
||||
is-air: bool,
|
||||
/// Whether this block is a liquid.
|
||||
is-liquid: bool,
|
||||
/// Whether this block is a solid.
|
||||
is-solid: bool,
|
||||
/// Whether this block occupies a full cube.
|
||||
is-full-cube: bool,
|
||||
/// How this block behaves when pushed by a piston.
|
||||
piston-behavior: piston-behavior,
|
||||
/// Whether this block receives random ticks.
|
||||
has-random-ticks: bool,
|
||||
}
|
||||
|
||||
/// A simple wrapper for a block state ID.
|
||||
record block-state-id {
|
||||
id: u16,
|
||||
}
|
||||
|
||||
/// A position in the world grid.
|
||||
record block-pos {
|
||||
x: s32,
|
||||
y: s32,
|
||||
z: s32,
|
||||
}
|
||||
|
||||
/// Represents a Minecraft world (dimension).
|
||||
resource %world {
|
||||
/// Returns the unique identifier of this world.
|
||||
get-id: func() -> string;
|
||||
|
||||
/// Gets the block state ID at the specified position.
|
||||
get-block-state-id: func(pos: block-pos) -> u16;
|
||||
|
||||
/// Gets detailed block state information at the specified position.
|
||||
get-block-state: func(pos: block-pos) -> block-state;
|
||||
|
||||
/// Sets the block state at the specified position.
|
||||
set-block-state: func(pos: block-pos, state: u16, update-flags: block-flags);
|
||||
|
||||
/// Returns the current time of day in ticks.
|
||||
get-time-of-day: func() -> u64;
|
||||
|
||||
/// Sets the current time of day in ticks.
|
||||
set-time-of-day: func(time: u64);
|
||||
|
||||
/// Returns the total age of the world in ticks.
|
||||
get-world-age: func() -> u64;
|
||||
|
||||
/// Returns the dimension type (e.g., "minecraft:overworld").
|
||||
get-dimension: func() -> string;
|
||||
|
||||
/// Gets the highest non-air block Y coordinate at the specified X and Z.
|
||||
get-top-block-y: func(x: s32, z: s32) -> s32;
|
||||
|
||||
/// Gets the highest motion-blocking block Y coordinate.
|
||||
get-motion-blocking-height: func(x: s32, z: s32) -> s32;
|
||||
|
||||
/// Returns whether it is currently raining or snowing.
|
||||
is-raining: func() -> bool;
|
||||
|
||||
/// Sets whether it should be raining or snowing.
|
||||
set-raining: func(raining: bool);
|
||||
|
||||
/// Returns whether there is currently a thunderstorm.
|
||||
is-thundering: func() -> bool;
|
||||
|
||||
/// Sets whether there should be a thunderstorm.
|
||||
set-thundering: func(thundering: bool);
|
||||
|
||||
/// Broadcasts a system message to all players in this world.
|
||||
broadcast-system-message: func(message: text-component, overlay: bool);
|
||||
|
||||
/// Returns the scoreboard associated with this world.
|
||||
get-scoreboard: func() -> scoreboard;
|
||||
|
||||
/// Plays a sound at the specified position for all players in the world.
|
||||
play-sound: func(sound: string, category: sound-category, pos: position, volume: f32, pitch: f32);
|
||||
|
||||
/// Spawns particles at the specified position.
|
||||
spawn-particle: func(particle: string, pos: position, offset: position, max-speed: f32, count: s32);
|
||||
|
||||
/// Creates an explosion at the specified position.
|
||||
create-explosion: func(pos: position, power: f32, create-fire: bool, interaction: explosion-interaction);
|
||||
|
||||
/// Returns the sea level of this world.
|
||||
get-sea-level: func() -> s32;
|
||||
|
||||
/// Returns the minimum Y coordinate (bottom of the world).
|
||||
get-min-y: func() -> s32;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user