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