elytra
This commit is contained in:
parent
758b466d8e
commit
6ef3d8b3f0
|
@ -0,0 +1,661 @@
|
|||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are 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.
|
||||
|
||||
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.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
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 Affero 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 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 running 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 to find the
|
||||
Corresponding Source. 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 though 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 license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(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 all recipients 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. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
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 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 work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
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 AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
|
@ -23,7 +23,7 @@ dependencies {
|
|||
}
|
||||
|
||||
teavm.js {
|
||||
obfuscated = false
|
||||
obfuscated = true
|
||||
sourceMap = false
|
||||
targetFileName = "../classes.js"
|
||||
optimization = org.teavm.gradle.api.OptimizationLevel.AGGRESSIVE
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"parent": "builtin/generated",
|
||||
"textures": {
|
||||
"layer0": "items/elytra"
|
||||
},
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ -90, 0, 0 ],
|
||||
"translation": [ 0, 1, -3 ],
|
||||
"scale": [ 0.55, 0.55, 0.55 ]
|
||||
},
|
||||
"firstperson": {
|
||||
"rotation": [ 0, -135, 25 ],
|
||||
"translation": [ 0, 4, 2 ],
|
||||
"scale": [ 1.7, 1.7, 1.7 ]
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 452 B |
Binary file not shown.
After Width: | Height: | Size: 326 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
1396743
javascript/classes.js
1396743
javascript/classes.js
File diff suppressed because it is too large
Load Diff
|
@ -26,24 +26,32 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformApplication {
|
||||
|
||||
|
||||
private static long win = 0l;
|
||||
|
||||
|
||||
static void initHooks(long glfwWindow) {
|
||||
win = glfwWindow;
|
||||
}
|
||||
|
@ -59,42 +67,42 @@ public class PlatformApplication {
|
|||
public static void setClipboard(String text) {
|
||||
glfwSetClipboardString(win, text);
|
||||
}
|
||||
|
||||
|
||||
public static String getClipboard() {
|
||||
String str = glfwGetClipboardString(win);
|
||||
return str == null ? "" : str;
|
||||
}
|
||||
|
||||
|
||||
public static void setLocalStorage(String name, byte[] data) {
|
||||
if(data == null) {
|
||||
(new File("_eagstorage."+name+".dat")).delete();
|
||||
}else {
|
||||
try(FileOutputStream f = new FileOutputStream(new File("_eagstorage."+name+".dat"))) {
|
||||
if (data == null) {
|
||||
(new File("_eagstorage." + name + ".dat")).delete();
|
||||
} else {
|
||||
try (FileOutputStream f = new FileOutputStream(new File("_eagstorage." + name + ".dat"))) {
|
||||
f.write(data);
|
||||
} catch (IOException e) {
|
||||
EagRuntime.debugPrintStackTrace(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getLocalStorage(String data) {
|
||||
File f = new File("_eagstorage."+data+".dat");
|
||||
if(!f.isFile()) {
|
||||
File f = new File("_eagstorage." + data + ".dat");
|
||||
if (!f.isFile()) {
|
||||
return null;
|
||||
}
|
||||
byte[] b = new byte[(int)f.length()];
|
||||
try(FileInputStream s = new FileInputStream(f)) {
|
||||
byte[] b = new byte[(int) f.length()];
|
||||
try (FileInputStream s = new FileInputStream(f)) {
|
||||
s.read(b);
|
||||
return b;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String saveScreenshot() {
|
||||
return "nothing";
|
||||
}
|
||||
|
||||
|
||||
public static void showPopup(String msg) {
|
||||
JOptionPane pane = new JOptionPane(msg, JOptionPane.WARNING_MESSAGE, JOptionPane.DEFAULT_OPTION, null,
|
||||
new Object[] { "OK" }, "OK");
|
||||
|
@ -111,13 +119,13 @@ public class PlatformApplication {
|
|||
dialog.setLocationRelativeTo(null);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
private static volatile boolean fileChooserOpen = false;
|
||||
private static volatile boolean fileChooserHasResult = false;
|
||||
private static volatile FileChooserResult fileChooserResultObject = null;
|
||||
|
||||
public static void displayFileChooser(final String mime, final String ext) {
|
||||
if(!fileChooserOpen) {
|
||||
if (!fileChooserOpen) {
|
||||
fileChooserOpen = true;
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
|
@ -135,20 +143,20 @@ public class PlatformApplication {
|
|||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.setFileFilter(new FileFilterExt(ext));
|
||||
if(fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
File f = fc.getSelectedFile();
|
||||
if(f != null) {
|
||||
if (f != null) {
|
||||
String name = f.getName();
|
||||
byte[] bytes = new byte[(int)f.length()];
|
||||
try(FileInputStream is = new FileInputStream(f)) {
|
||||
byte[] bytes = new byte[(int) f.length()];
|
||||
try (FileInputStream is = new FileInputStream(f)) {
|
||||
is.read(bytes);
|
||||
}
|
||||
fileChooserResultObject = new FileChooserResult(name, bytes);
|
||||
}else {
|
||||
} else {
|
||||
fileChooserResultObject = null;
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
fileChooserResultObject = null;
|
||||
}
|
||||
fileChooserOpen = false;
|
||||
|
@ -156,17 +164,17 @@ public class PlatformApplication {
|
|||
}
|
||||
|
||||
private static class FileChooserAlwaysOnTop extends JFileChooser {
|
||||
|
||||
|
||||
private FileChooserAlwaysOnTop(File file) {
|
||||
super(file);
|
||||
}
|
||||
|
||||
|
||||
protected JDialog createDialog(Component parent) throws HeadlessException {
|
||||
JDialog dialog = super.createDialog(parent);
|
||||
dialog.setAlwaysOnTop(true);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static class FileFilterExt extends FileFilter {
|
||||
|
@ -208,7 +216,7 @@ public class PlatformApplication {
|
|||
private static MainMenuCreditsDialog creditsDialog = null;
|
||||
|
||||
public static void openCreditsPopup(String text) {
|
||||
if(creditsDialog == null) {
|
||||
if (creditsDialog == null) {
|
||||
creditsDialog = new MainMenuCreditsDialog();
|
||||
}
|
||||
creditsDialog.setCreditsText(text);
|
||||
|
@ -220,16 +228,16 @@ public class PlatformApplication {
|
|||
private static final Logger downloadsLogger = LogManager.getLogger("DownloadsFolder");
|
||||
|
||||
public static void downloadFileWithName(String fileName, byte[] fileContents) {
|
||||
if(!downloadsDirectory.isDirectory() && !downloadsDirectory.mkdirs()) {
|
||||
if (!downloadsDirectory.isDirectory() && !downloadsDirectory.mkdirs()) {
|
||||
throw new RuntimeException("Could not create directory: " + downloadsDirectory.getAbsolutePath());
|
||||
}
|
||||
|
||||
File f = new File(downloadsDirectory, fileName);
|
||||
if(f.exists()) {
|
||||
if (f.exists()) {
|
||||
String name = fileName;
|
||||
String ext = "";
|
||||
int i = fileName.lastIndexOf('.');
|
||||
if(i != -1) {
|
||||
if (i != -1) {
|
||||
name = fileName.substring(0, i);
|
||||
ext = fileName.substring(i);
|
||||
}
|
||||
|
@ -237,12 +245,12 @@ public class PlatformApplication {
|
|||
i = 0;
|
||||
do {
|
||||
f = new File(downloadsDirectory, name + " (" + (++i) + ")" + ext);
|
||||
}while(f.exists());
|
||||
} while (f.exists());
|
||||
}
|
||||
|
||||
try(FileOutputStream fos = new FileOutputStream(f)) {
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
fos.write(fileContents);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Could not save file: " + f.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
@ -250,12 +258,12 @@ public class PlatformApplication {
|
|||
|
||||
try {
|
||||
Desktop.getDesktop().open(downloadsDirectory);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addLogMessage(String logMessage, boolean isError) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static boolean isShowingDebugConsole() {
|
||||
|
@ -263,7 +271,7 @@ public class PlatformApplication {
|
|||
}
|
||||
|
||||
public static void showDebugConsole() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,53 +14,61 @@ import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
|
|||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformAssets {
|
||||
|
||||
|
||||
static URL getDesktopResourceURL(String path) {
|
||||
File f = new File("resources", path);
|
||||
if(f.isFile()) {
|
||||
if (f.isFile()) {
|
||||
try {
|
||||
return f.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final byte[] getResourceBytes(String path) {
|
||||
File loadFile = new File("resources", path);
|
||||
byte[] ret = new byte[(int) loadFile.length()];
|
||||
try(FileInputStream is = new FileInputStream(loadFile)) {
|
||||
try (FileInputStream is = new FileInputStream(loadFile)) {
|
||||
int i, j = 0;
|
||||
while(j < ret.length && (i = is.read(ret, j, ret.length - j)) != -1) {
|
||||
while (j < ret.length && (i = is.read(ret, j, ret.length - j)) != -1) {
|
||||
j += i;
|
||||
}
|
||||
return ret;
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final ImageData loadImageFile(InputStream data) {
|
||||
try {
|
||||
BufferedImage img = ImageIO.read(data);
|
||||
if(img == null) {
|
||||
if (img == null) {
|
||||
throw new IOException("Data is not a supported image format!");
|
||||
}
|
||||
int w = img.getWidth();
|
||||
|
@ -68,22 +76,22 @@ public class PlatformAssets {
|
|||
boolean a = img.getColorModel().hasAlpha();
|
||||
int[] pixels = new int[w * h];
|
||||
img.getRGB(0, 0, w, h, pixels, 0, w);
|
||||
for(int i = 0; i < pixels.length; ++i) {
|
||||
for (int i = 0; i < pixels.length; ++i) {
|
||||
int j = pixels[i];
|
||||
if(!a) {
|
||||
if (!a) {
|
||||
j = j | 0xFF000000;
|
||||
}
|
||||
pixels[i] = (j & 0xFF00FF00) | ((j & 0x00FF0000) >> 16) |
|
||||
((j & 0x000000FF) << 16);
|
||||
}
|
||||
return new ImageData(w, h, pixels, a);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final ImageData loadImageFile(byte[] data) {
|
||||
return loadImageFile(new EaglerInputStream(data));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,37 +13,45 @@ import paulscode.sound.codecs.CodecJOrbis;
|
|||
import paulscode.sound.codecs.CodecWav;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformAudio {
|
||||
|
||||
|
||||
protected static class PaulscodeAudioResource implements IAudioResource {
|
||||
|
||||
|
||||
protected final URL resourceLoc;
|
||||
|
||||
|
||||
protected PaulscodeAudioResource(URL resourceLoc) {
|
||||
this.resourceLoc = resourceLoc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected static class PaulscodeAudioHandle implements IAudioHandle {
|
||||
|
||||
|
||||
protected final String sourceName;
|
||||
protected long stall;
|
||||
|
||||
|
||||
protected PaulscodeAudioHandle(String sourceName) {
|
||||
this.sourceName = sourceName;
|
||||
this.stall = System.currentTimeMillis();
|
||||
|
@ -51,12 +59,12 @@ public class PlatformAudio {
|
|||
|
||||
@Override
|
||||
public void pause(boolean setPaused) {
|
||||
if(setPaused) {
|
||||
if(sndSystem.playing(sourceName)) {
|
||||
if (setPaused) {
|
||||
if (sndSystem.playing(sourceName)) {
|
||||
sndSystem.pause(sourceName);
|
||||
}
|
||||
}else {
|
||||
if(!sndSystem.playing(sourceName)) {
|
||||
} else {
|
||||
if (!sndSystem.playing(sourceName)) {
|
||||
sndSystem.play(sourceName);
|
||||
}
|
||||
}
|
||||
|
@ -91,26 +99,27 @@ public class PlatformAudio {
|
|||
|
||||
@Override
|
||||
public boolean shouldFree() {
|
||||
return !sndSystem.playing(sourceName) && System.currentTimeMillis() - this.stall > 250l; //TODO: I hate this hack
|
||||
return !sndSystem.playing(sourceName) && System.currentTimeMillis() - this.stall > 250l; // TODO: I hate
|
||||
// this hack
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static IAudioResource loadAudioData(String filename, boolean holdInCache) {
|
||||
URL ret = PlatformAssets.getDesktopResourceURL(filename);
|
||||
if(ret != null) {
|
||||
if (ret != null) {
|
||||
return new PaulscodeAudioResource(ret);
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void clearAudioCache() {
|
||||
// browser only
|
||||
}
|
||||
|
||||
public static void flushAudioCache() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static interface IAudioCacheLoader {
|
||||
|
@ -120,10 +129,10 @@ public class PlatformAudio {
|
|||
public static IAudioResource loadAudioDataNew(String filename, boolean holdInCache, IAudioCacheLoader loader) {
|
||||
throw new UnsupportedOperationException("Browser only!");
|
||||
}
|
||||
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("EaglercraftPlatformAudio");
|
||||
private static SoundSystem sndSystem = null;
|
||||
|
||||
|
||||
static void platformInitialize() {
|
||||
logger.info("Eaglercraft still uses Paul Lamb's SoundSystem but with LWJGL3");
|
||||
logger.info(" \"Author: Paul Lamb, www.paulscode.com\"");
|
||||
|
@ -137,11 +146,13 @@ public class PlatformAudio {
|
|||
logger.info(parString1);
|
||||
}
|
||||
}
|
||||
|
||||
public void importantMessage(String parString1, int parInt1) {
|
||||
if (!parString1.isEmpty()) {
|
||||
logger.warn(parString1);
|
||||
}
|
||||
}
|
||||
|
||||
public void errorMessage(String parString1, String parString2, int parInt1) {
|
||||
if (!parString2.isEmpty()) {
|
||||
logger.error("Error in class \"{}\"!", parString1);
|
||||
|
@ -150,66 +161,66 @@ public class PlatformAudio {
|
|||
}
|
||||
});
|
||||
sndSystem = new SoundSystem();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Could not initialize Paulscode SoundSystem! Is this system's OpenAL installed correctly?");
|
||||
logger.error(t);
|
||||
sndSystem = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void platformShutdown() {
|
||||
if(sndSystem != null) {
|
||||
if (sndSystem != null) {
|
||||
sndSystem.cleanup();
|
||||
sndSystem = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean available() {
|
||||
return sndSystem != null;
|
||||
}
|
||||
|
||||
|
||||
private static int sourceCounter = 0;
|
||||
|
||||
|
||||
public static IAudioHandle beginPlayback(IAudioResource track, float x, float y, float z,
|
||||
float volume, float pitch) {
|
||||
if(sndSystem == null) {
|
||||
if (sndSystem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
float f1 = 16.0F;
|
||||
if (volume > 1.0F) {
|
||||
f1 *= volume;
|
||||
}
|
||||
|
||||
|
||||
String srcName = "src" + ++sourceCounter;
|
||||
sndSystem.newSource(false, srcName, ((PaulscodeAudioResource)track).resourceLoc,
|
||||
((PaulscodeAudioResource)track).resourceLoc.getPath(), false, x, y, z, 2, f1);
|
||||
sndSystem.newSource(false, srcName, ((PaulscodeAudioResource) track).resourceLoc,
|
||||
((PaulscodeAudioResource) track).resourceLoc.getPath(), false, x, y, z, 2, f1);
|
||||
sndSystem.setTemporary(srcName, true);
|
||||
sndSystem.setPitch(srcName, pitch);
|
||||
sndSystem.setVolume(srcName, volume);
|
||||
sndSystem.play(srcName);
|
||||
|
||||
|
||||
return new PaulscodeAudioHandle(srcName);
|
||||
}
|
||||
|
||||
|
||||
public static IAudioHandle beginPlaybackStatic(IAudioResource track, float volume, float pitch) {
|
||||
if(sndSystem == null) {
|
||||
if (sndSystem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
String srcName = "src" + ++sourceCounter;
|
||||
sndSystem.newSource(false, srcName, ((PaulscodeAudioResource)track).resourceLoc,
|
||||
((PaulscodeAudioResource)track).resourceLoc.getPath(), false, 0.0f, 0.0f, 0.0f, 0, 0.0f);
|
||||
sndSystem.newSource(false, srcName, ((PaulscodeAudioResource) track).resourceLoc,
|
||||
((PaulscodeAudioResource) track).resourceLoc.getPath(), false, 0.0f, 0.0f, 0.0f, 0, 0.0f);
|
||||
sndSystem.setTemporary(srcName, true);
|
||||
sndSystem.setPitch(srcName, pitch);
|
||||
sndSystem.setVolume(srcName, volume);
|
||||
sndSystem.play(srcName);
|
||||
|
||||
|
||||
return new PaulscodeAudioHandle(srcName);
|
||||
}
|
||||
|
||||
|
||||
public static void setListener(float x, float y, float z, float pitchDegrees, float yawDegrees) {
|
||||
if(sndSystem == null) {
|
||||
if (sndSystem == null) {
|
||||
return;
|
||||
}
|
||||
float f2 = MathHelper.cos((yawDegrees + 90.0F) * 0.017453292F);
|
||||
|
|
|
@ -4,16 +4,24 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
|||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -30,5 +38,5 @@ public class PlatformBufferFunctions {
|
|||
intBuffer.put(data);
|
||||
intBuffer.position(p);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -10,31 +10,39 @@ import org.lwjgl.glfw.GLFWVidMode;
|
|||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformInput {
|
||||
|
||||
|
||||
private static long win = 0l;
|
||||
|
||||
private static long cursorDefault = 0l;
|
||||
private static long cursorHand = 0l;
|
||||
private static long cursorText = 0l;
|
||||
|
||||
|
||||
private static boolean windowFocused = true;
|
||||
private static boolean windowResized = true;
|
||||
|
||||
|
||||
private static boolean windowCursorEntered = true;
|
||||
private static boolean windowMouseGrabbed = false;
|
||||
private static int cursorX = 0;
|
||||
|
@ -42,15 +50,15 @@ public class PlatformInput {
|
|||
private static int cursorDX = 0;
|
||||
private static int cursorDY = 0;
|
||||
private static int DWheel = 0;
|
||||
|
||||
|
||||
private static int windowWidth = 640;
|
||||
private static int windowHeight = 480;
|
||||
|
||||
|
||||
private static final List<KeyboardEvent> keyboardEventList = new LinkedList();
|
||||
private static KeyboardEvent currentKeyboardEvent = null;
|
||||
|
||||
|
||||
private static final char[] keyboardReleaseEventChars = new char[256];
|
||||
|
||||
|
||||
private static boolean enableRepeatEvents = false;
|
||||
private static int functionKeyModifier = GLFW_KEY_F;
|
||||
|
||||
|
@ -62,31 +70,31 @@ public class PlatformInput {
|
|||
private static boolean glfwVSyncState = false;
|
||||
|
||||
private static class KeyboardEvent {
|
||||
|
||||
|
||||
protected final int key;
|
||||
protected final boolean pressed;
|
||||
protected final boolean repeating;
|
||||
protected char resolvedCharacter = '\0';
|
||||
|
||||
|
||||
protected KeyboardEvent(int key, boolean pressed, boolean repeating) {
|
||||
this.key = key;
|
||||
this.pressed = pressed;
|
||||
this.repeating = repeating;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static final List<MouseEvent> mouseEventList = new LinkedList();
|
||||
private static MouseEvent currentMouseEvent = null;
|
||||
|
||||
|
||||
private static class MouseEvent {
|
||||
|
||||
|
||||
protected final int button;
|
||||
protected final boolean pressed;
|
||||
protected final int posX;
|
||||
protected final int posY;
|
||||
protected final float wheel;
|
||||
|
||||
|
||||
protected MouseEvent(int button, boolean pressed, int posX, int posY, float wheel) {
|
||||
this.button = button;
|
||||
this.pressed = pressed;
|
||||
|
@ -94,16 +102,16 @@ public class PlatformInput {
|
|||
this.posY = posY;
|
||||
this.wheel = wheel;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void initHooks(long glfwWindow) {
|
||||
win = glfwWindow;
|
||||
|
||||
|
||||
glfwSetErrorCallback((arg0, arg1) -> {
|
||||
String errorString = "<null>";
|
||||
if(arg1 != 0l) {
|
||||
try(MemoryStack stack = MemoryStack.stackPush()) {
|
||||
if (arg1 != 0l) {
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
PointerBuffer pbuffer = stack.mallocPointer(1);
|
||||
pbuffer.put(0, arg1);
|
||||
errorString = pbuffer.getStringUTF8(0);
|
||||
|
@ -111,82 +119,82 @@ public class PlatformInput {
|
|||
}
|
||||
PlatformRuntime.logger.error("GLFW Error #{}: {}", arg0, errorString);
|
||||
});
|
||||
|
||||
if(!glfwRawMouseMotionSupported()) {
|
||||
|
||||
if (!glfwRawMouseMotionSupported()) {
|
||||
throw new UnsupportedOperationException("Raw mouse movement (cursor lock) is not supported!");
|
||||
}
|
||||
|
||||
|
||||
int[] v1 = new int[1], v2 = new int[1];
|
||||
glfwGetFramebufferSize(glfwWindow, v1, v2);
|
||||
|
||||
|
||||
windowWidth = v1[0];
|
||||
windowHeight = v2[0];
|
||||
|
||||
|
||||
glfwSetFramebufferSizeCallback(glfwWindow, (window, width, height) -> {
|
||||
windowWidth = width;
|
||||
windowHeight = height;
|
||||
windowResized = true;
|
||||
});
|
||||
|
||||
|
||||
glfwSetWindowFocusCallback(glfwWindow, (window, focused) -> {
|
||||
windowFocused = focused;
|
||||
});
|
||||
|
||||
|
||||
glfwSetKeyCallback(glfwWindow, (window, key, scancode, action, mods) -> {
|
||||
if (key == GLFW_KEY_F11 && action == GLFW_PRESS) {
|
||||
toggleFullscreen();
|
||||
}
|
||||
if(glfwGetKey(glfwWindow, functionKeyModifier) == GLFW_PRESS) {
|
||||
if(key >= GLFW_KEY_1 && key <= GLFW_KEY_9) {
|
||||
if (glfwGetKey(glfwWindow, functionKeyModifier) == GLFW_PRESS) {
|
||||
if (key >= GLFW_KEY_1 && key <= GLFW_KEY_9) {
|
||||
key = key - GLFW_KEY_1 + GLFW_KEY_F1;
|
||||
}
|
||||
}
|
||||
key = KeyboardConstants.getEaglerKeyFromGLFW(key);
|
||||
keyboardEventList.add(new KeyboardEvent(key, action != GLFW_RELEASE, action == GLFW_REPEAT));
|
||||
if(keyboardEventList.size() > 64) {
|
||||
if (keyboardEventList.size() > 64) {
|
||||
keyboardEventList.remove(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
glfwSetCharCallback(glfwWindow, (window, character) -> {
|
||||
keyboardCharList.add(Character.valueOf((char)character));
|
||||
if(keyboardCharList.size() > 64) {
|
||||
keyboardCharList.add(Character.valueOf((char) character));
|
||||
if (keyboardCharList.size() > 64) {
|
||||
keyboardCharList.remove(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
glfwSetCursorPosCallback(glfwWindow, (window, posX, posY) -> {
|
||||
posY = windowHeight - posY;
|
||||
if(windowMouseGrabbed) {
|
||||
cursorDX -= (cursorX - (int)posX);
|
||||
cursorDY -= (cursorY - (int)posY);
|
||||
cursorX = (int)posX;
|
||||
cursorY = (int)posY;
|
||||
}else {
|
||||
cursorX = (int)posX;
|
||||
cursorY = (int)posY;
|
||||
if (windowMouseGrabbed) {
|
||||
cursorDX -= (cursorX - (int) posX);
|
||||
cursorDY -= (cursorY - (int) posY);
|
||||
cursorX = (int) posX;
|
||||
cursorY = (int) posY;
|
||||
} else {
|
||||
cursorX = (int) posX;
|
||||
cursorY = (int) posY;
|
||||
mouseEventList.add(new MouseEvent(-1, false, cursorX, cursorY, 0.0f));
|
||||
if(mouseEventList.size() > 64) {
|
||||
if (mouseEventList.size() > 64) {
|
||||
mouseEventList.remove(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
glfwSetMouseButtonCallback(glfwWindow, (window, button, action, mods) -> {
|
||||
mouseEventList.add(new MouseEvent(button, action != GLFW_RELEASE, cursorX, cursorY, 0.0f));
|
||||
if(mouseEventList.size() > 64) {
|
||||
if (mouseEventList.size() > 64) {
|
||||
mouseEventList.remove(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
glfwSetCursorEnterCallback(glfwWindow, (window, enter) -> {
|
||||
windowCursorEntered = enter;
|
||||
});
|
||||
|
||||
|
||||
glfwSetScrollCallback(glfwWindow, (window, scrollX, scrollY) -> {
|
||||
DWheel += (int)scrollY;
|
||||
mouseEventList.add(new MouseEvent(-1, false, cursorX, cursorY, (float)scrollY));
|
||||
if(mouseEventList.size() > 64) {
|
||||
DWheel += (int) scrollY;
|
||||
mouseEventList.add(new MouseEvent(-1, false, cursorX, cursorY, (float) scrollY));
|
||||
if (mouseEventList.size() > 64) {
|
||||
mouseEventList.remove(0);
|
||||
}
|
||||
});
|
||||
|
@ -196,15 +204,15 @@ public class PlatformInput {
|
|||
cursorText = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
|
||||
glfwSetCursor(glfwWindow, cursorDefault);
|
||||
|
||||
if(!fullscreen && startupFullscreen) {
|
||||
if (!fullscreen && startupFullscreen) {
|
||||
toggleFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int getWindowWidth() {
|
||||
return windowWidth;
|
||||
}
|
||||
|
||||
|
||||
public static int getWindowHeight() {
|
||||
return windowHeight;
|
||||
}
|
||||
|
@ -223,7 +231,7 @@ public class PlatformInput {
|
|||
|
||||
public static void update() {
|
||||
glfwPollEvents();
|
||||
if(vsync != glfwVSyncState) {
|
||||
if (vsync != glfwVSyncState) {
|
||||
glfwSwapInterval(vsync ? 1 : 0);
|
||||
glfwVSyncState = vsync;
|
||||
}
|
||||
|
@ -237,34 +245,32 @@ public class PlatformInput {
|
|||
}
|
||||
|
||||
public static boolean keyboardNext() {
|
||||
if(keyboardEventList.size() > 0) {
|
||||
if (keyboardEventList.size() > 0) {
|
||||
currentKeyboardEvent = keyboardEventList.remove(0);
|
||||
if(currentKeyboardEvent.resolvedCharacter == '\0' && KeyboardConstants
|
||||
if (currentKeyboardEvent.resolvedCharacter == '\0' && KeyboardConstants
|
||||
.getKeyCharFromEagler(currentKeyboardEvent.key) != '\0') {
|
||||
if(currentKeyboardEvent.pressed && keyboardCharList.size() > 0) {
|
||||
if (currentKeyboardEvent.pressed && keyboardCharList.size() > 0) {
|
||||
currentKeyboardEvent.resolvedCharacter = keyboardCharList.remove(0);
|
||||
keyboardReleaseEventChars[currentKeyboardEvent.key] =
|
||||
currentKeyboardEvent.resolvedCharacter;
|
||||
}else if(!currentKeyboardEvent.pressed) {
|
||||
currentKeyboardEvent.resolvedCharacter =
|
||||
keyboardReleaseEventChars[currentKeyboardEvent.key];
|
||||
keyboardReleaseEventChars[currentKeyboardEvent.key] = currentKeyboardEvent.resolvedCharacter;
|
||||
} else if (!currentKeyboardEvent.pressed) {
|
||||
currentKeyboardEvent.resolvedCharacter = keyboardReleaseEventChars[currentKeyboardEvent.key];
|
||||
keyboardReleaseEventChars[currentKeyboardEvent.key] = '\0';
|
||||
}
|
||||
}
|
||||
if(currentKeyboardEvent.repeating && !enableRepeatEvents) {
|
||||
if (currentKeyboardEvent.repeating && !enableRepeatEvents) {
|
||||
return keyboardNext();
|
||||
}else {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}else {
|
||||
if(keyboardCharList.size() > 0) {
|
||||
} else {
|
||||
if (keyboardCharList.size() > 0) {
|
||||
currentKeyboardEvent = new KeyboardEvent(KeyboardConstants.KEY_SPACE, true, false);
|
||||
currentKeyboardEvent.resolvedCharacter = keyboardCharList.remove(0);
|
||||
KeyboardEvent releaseEvent = new KeyboardEvent(KeyboardConstants.KEY_SPACE, false, false);
|
||||
releaseEvent.resolvedCharacter = currentKeyboardEvent.resolvedCharacter;
|
||||
keyboardEventList.add(releaseEvent);
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -283,11 +289,11 @@ public class PlatformInput {
|
|||
}
|
||||
|
||||
public static boolean keyboardIsKeyDown(int key) {
|
||||
if(glfwGetKey(win, functionKeyModifier) == GLFW_PRESS) {
|
||||
if(key >= GLFW_KEY_1 && key <= GLFW_KEY_9) {
|
||||
if (glfwGetKey(win, functionKeyModifier) == GLFW_PRESS) {
|
||||
if (key >= GLFW_KEY_1 && key <= GLFW_KEY_9) {
|
||||
return false;
|
||||
}
|
||||
if(key >= GLFW_KEY_F1 && key <= GLFW_KEY_F9) {
|
||||
if (key >= GLFW_KEY_F1 && key <= GLFW_KEY_F9) {
|
||||
key = key - GLFW_KEY_F1 + GLFW_KEY_1;
|
||||
}
|
||||
}
|
||||
|
@ -303,10 +309,10 @@ public class PlatformInput {
|
|||
}
|
||||
|
||||
public static boolean mouseNext() {
|
||||
if(mouseEventList.size() > 0) {
|
||||
if (mouseEventList.size() > 0) {
|
||||
currentMouseEvent = mouseEventList.remove(0);
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +334,7 @@ public class PlatformInput {
|
|||
}
|
||||
|
||||
public static int mouseGetEventDWheel() {
|
||||
return (int)currentMouseEvent.wheel;
|
||||
return (int) currentMouseEvent.wheel;
|
||||
}
|
||||
|
||||
public static int mouseGetX() {
|
||||
|
@ -350,7 +356,7 @@ public class PlatformInput {
|
|||
}
|
||||
|
||||
public static void mouseSetGrabbed(boolean grab) {
|
||||
if(grab != windowMouseGrabbed) {
|
||||
if (grab != windowMouseGrabbed) {
|
||||
cursorX = windowWidth / 2;
|
||||
cursorY = windowHeight / 2;
|
||||
glfwSetCursorPos(win, cursorX, cursorY);
|
||||
|
@ -391,7 +397,7 @@ public class PlatformInput {
|
|||
public static boolean mouseIsInsideWindow() {
|
||||
return windowCursorEntered;
|
||||
}
|
||||
|
||||
|
||||
public static boolean contextLost() {
|
||||
return glfwGetWindowAttrib(win, GLFW_ICONIFIED) == GLFW_TRUE;
|
||||
}
|
||||
|
@ -448,9 +454,8 @@ public class PlatformInput {
|
|||
mw[0] = mode.width();
|
||||
mh[0] = mode.height();
|
||||
|
||||
overlap =
|
||||
Math.max(0, Math.min(wx[0] + ww[0], mx[0] + mw[0]) - Math.max(wx[0], mx[0])) *
|
||||
Math.max(0, Math.min(wy[0] + wh[0], my[0] + mh[0]) - Math.max(wy[0], my[0]));
|
||||
overlap = Math.max(0, Math.min(wx[0] + ww[0], mx[0] + mw[0]) - Math.max(wx[0], mx[0])) *
|
||||
Math.max(0, Math.min(wy[0] + wh[0], my[0] + mh[0]) - Math.max(wy[0], my[0]));
|
||||
|
||||
if (bestoverlap < overlap) {
|
||||
bestoverlap = overlap;
|
||||
|
@ -466,17 +471,17 @@ public class PlatformInput {
|
|||
}
|
||||
|
||||
public static void showCursor(EnumCursorType cursor) {
|
||||
switch(cursor) {
|
||||
case DEFAULT:
|
||||
default:
|
||||
glfwSetCursor(win, cursorDefault);
|
||||
break;
|
||||
case HAND:
|
||||
glfwSetCursor(win, cursorHand);
|
||||
break;
|
||||
case TEXT:
|
||||
glfwSetCursor(win, cursorText);
|
||||
break;
|
||||
switch (cursor) {
|
||||
case DEFAULT:
|
||||
default:
|
||||
glfwSetCursor(win, cursorDefault);
|
||||
break;
|
||||
case HAND:
|
||||
glfwSetCursor(win, cursorHand);
|
||||
break;
|
||||
case TEXT:
|
||||
glfwSetCursor(win, cursorText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,67 +12,81 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformNetworking {
|
||||
|
||||
|
||||
static final Logger networkLogger = LogManager.getLogger("PlatformNetworking");
|
||||
|
||||
|
||||
private static WebSocketPlayClient wsPlayClient = null;
|
||||
static EnumEaglerConnectionState playConnectState = EnumEaglerConnectionState.CLOSED;
|
||||
static EnumServerRateLimit serverRateLimit = null;
|
||||
|
||||
|
||||
static String currentURI = null;
|
||||
|
||||
|
||||
public static EnumEaglerConnectionState playConnectionState() {
|
||||
return ((wsPlayClient == null || wsPlayClient.isClosed()) && playConnectState == EnumEaglerConnectionState.CONNECTING) ? EnumEaglerConnectionState.FAILED :
|
||||
((wsPlayClient != null && wsPlayClient.getReadyState() == ReadyState.NOT_YET_CONNECTED) ? EnumEaglerConnectionState.CONNECTING :
|
||||
(((wsPlayClient == null || wsPlayClient.isClosed()) && playConnectState != EnumEaglerConnectionState.FAILED) ? EnumEaglerConnectionState.CLOSED : playConnectState));
|
||||
return ((wsPlayClient == null || wsPlayClient.isClosed())
|
||||
&& playConnectState == EnumEaglerConnectionState.CONNECTING)
|
||||
? EnumEaglerConnectionState.FAILED
|
||||
: ((wsPlayClient != null && wsPlayClient.getReadyState() == ReadyState.NOT_YET_CONNECTED)
|
||||
? EnumEaglerConnectionState.CONNECTING
|
||||
: (((wsPlayClient == null || wsPlayClient.isClosed())
|
||||
&& playConnectState != EnumEaglerConnectionState.FAILED)
|
||||
? EnumEaglerConnectionState.CLOSED
|
||||
: playConnectState));
|
||||
}
|
||||
|
||||
|
||||
public static void startPlayConnection(String destination) {
|
||||
if(!playConnectionState().isClosed()) {
|
||||
if (!playConnectionState().isClosed()) {
|
||||
networkLogger.warn("Tried connecting to a server while already connected to a different server!");
|
||||
playDisconnect();
|
||||
}
|
||||
|
||||
|
||||
currentURI = destination;
|
||||
|
||||
synchronized(playPackets) {
|
||||
|
||||
synchronized (playPackets) {
|
||||
playPackets.clear();
|
||||
}
|
||||
|
||||
|
||||
playConnectState = EnumEaglerConnectionState.CONNECTING;
|
||||
networkLogger.info("Connecting to server: {}", destination);
|
||||
|
||||
|
||||
URI u;
|
||||
|
||||
|
||||
try {
|
||||
u = new URI(destination);
|
||||
}catch(URISyntaxException ex) {
|
||||
} catch (URISyntaxException ex) {
|
||||
networkLogger.error("Invalid server URI: {}", destination);
|
||||
playConnectState = EnumEaglerConnectionState.FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
wsPlayClient = new WebSocketPlayClient(u);
|
||||
wsPlayClient.connect();
|
||||
}
|
||||
|
||||
|
||||
public static void playDisconnect() {
|
||||
if(!playConnectionState().isClosed() && wsPlayClient != null) {
|
||||
if (!playConnectionState().isClosed() && wsPlayClient != null) {
|
||||
try {
|
||||
wsPlayClient.closeBlocking();
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -81,71 +95,71 @@ public class PlatformNetworking {
|
|||
playConnectState = EnumEaglerConnectionState.CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final List<byte[]> playPackets = new LinkedList();
|
||||
|
||||
|
||||
public static byte[] readPlayPacket() {
|
||||
synchronized(playPackets) {
|
||||
synchronized (playPackets) {
|
||||
return playPackets.size() > 0 ? playPackets.remove(0) : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static List<byte[]> readAllPacket() {
|
||||
synchronized(playPackets) {
|
||||
if(!playPackets.isEmpty()) {
|
||||
synchronized (playPackets) {
|
||||
if (!playPackets.isEmpty()) {
|
||||
List<byte[]> ret = new ArrayList<>(playPackets);
|
||||
playPackets.clear();
|
||||
return ret;
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int countAvailableReadData() {
|
||||
int total = 0;
|
||||
synchronized(playPackets) {
|
||||
for(int i = 0, l = playPackets.size(); i < l; ++i) {
|
||||
synchronized (playPackets) {
|
||||
for (int i = 0, l = playPackets.size(); i < l; ++i) {
|
||||
total += playPackets.get(i).length;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
static void recievedPlayPacket(byte[] arg0) {
|
||||
synchronized(playPackets) {
|
||||
synchronized (playPackets) {
|
||||
playPackets.add(arg0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void writePlayPacket(byte[] pkt) {
|
||||
if(wsPlayClient == null || wsPlayClient.isClosed()) {
|
||||
if (wsPlayClient == null || wsPlayClient.isClosed()) {
|
||||
networkLogger.error("Tried to send {} byte play packet while the socket was closed!", pkt.length);
|
||||
}else {
|
||||
} else {
|
||||
wsPlayClient.send(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static IServerQuery sendServerQuery(String uri, String accept) {
|
||||
URI u;
|
||||
|
||||
|
||||
try {
|
||||
u = new URI(uri);
|
||||
}catch(URISyntaxException ex) {
|
||||
} catch (URISyntaxException ex) {
|
||||
networkLogger.error("Invalid server URI: {}", uri);
|
||||
playConnectState = EnumEaglerConnectionState.FAILED;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return new WebSocketServerQuery(accept, u);
|
||||
}
|
||||
|
||||
|
||||
public static EnumServerRateLimit getRateLimit() {
|
||||
return serverRateLimit == null ? EnumServerRateLimit.OK : serverRateLimit;
|
||||
}
|
||||
|
||||
|
||||
public static String getCurrentURI() {
|
||||
return currentURI;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -10,16 +10,24 @@ import static org.lwjgl.opengles.GLES30.*;
|
|||
import org.lwjgl.opengles.GLESCapabilities;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -301,7 +309,8 @@ public class PlatformOpenGL {
|
|||
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data));
|
||||
}
|
||||
|
||||
public static final void _wglTexSubImage2Du16(int target, int level, int xoffset, int yoffset, int width, int height,
|
||||
public static final void _wglTexSubImage2Du16(int target, int level, int xoffset, int yoffset, int width,
|
||||
int height,
|
||||
int format, int type, ByteBuffer data) {
|
||||
nglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
|
||||
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data));
|
||||
|
@ -482,9 +491,9 @@ public class PlatformOpenGL {
|
|||
}
|
||||
|
||||
public static final void _wglBindFramebuffer(int target, IFramebufferGL framebuffer) {
|
||||
if(framebuffer == null) {
|
||||
if (framebuffer == null) {
|
||||
glBindFramebuffer(target, 0);
|
||||
}else {
|
||||
} else {
|
||||
glBindFramebuffer(target, ((OpenGLObjects.FramebufferGL) framebuffer).ptr);
|
||||
}
|
||||
}
|
||||
|
@ -498,7 +507,8 @@ public class PlatformOpenGL {
|
|||
glFramebufferTexture2D(target, attachment, texTarget, ((OpenGLObjects.TextureGL) texture).ptr, level);
|
||||
}
|
||||
|
||||
public static final void _wglFramebufferTextureLayer(int target, int attachment, ITextureGL texture, int level, int layer) {
|
||||
public static final void _wglFramebufferTextureLayer(int target, int attachment, ITextureGL texture, int level,
|
||||
int layer) {
|
||||
glFramebufferTextureLayer(target, attachment, ((OpenGLObjects.TextureGL) texture).ptr, level, layer);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,44 +47,52 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
|||
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformRuntime {
|
||||
|
||||
|
||||
static final Logger logger = LogManager.getLogger("RuntimeLWJGL3");
|
||||
|
||||
|
||||
private static String glVersion = "unknown";
|
||||
private static String glRenderer = "unknown";
|
||||
|
||||
private static EnumPlatformANGLE rendererANGLEPlatform = null;
|
||||
|
||||
|
||||
private static long windowHandle = 0l;
|
||||
|
||||
public static void create() {
|
||||
logger.info("Starting Desktop Runtime...");
|
||||
PlatformFilesystem.initialize();
|
||||
EaglerFolderResourcePack.setSupported(true);
|
||||
|
||||
if(requestedANGLEPlatform != EnumPlatformANGLE.DEFAULT) {
|
||||
|
||||
if (requestedANGLEPlatform != EnumPlatformANGLE.DEFAULT) {
|
||||
logger.info("Setting ANGLE Platform: {}", requestedANGLEPlatform.name);
|
||||
glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE, requestedANGLEPlatform.eglEnum);
|
||||
}
|
||||
|
||||
|
||||
glfwInit();
|
||||
logger.info("GLFW Version: {}", glfwGetVersionString());
|
||||
|
||||
|
||||
glfwDefaultWindowHints();
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
|
@ -96,7 +104,6 @@ public class PlatformRuntime {
|
|||
|
||||
glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||
|
||||
|
||||
PointerBuffer buf = glfwGetMonitors();
|
||||
GLFWVidMode mon = glfwGetVideoMode(buf.get(0));
|
||||
|
@ -106,127 +113,159 @@ public class PlatformRuntime {
|
|||
|
||||
int winX = (mon.width() - windowWidth) / 2;
|
||||
int winY = (mon.height() - windowHeight - 20) / 2;
|
||||
|
||||
|
||||
windowHandle = glfwCreateWindow(windowWidth, windowHeight, "Eaglercraft Desktop Runtime", 0l, 0l);
|
||||
|
||||
|
||||
glfwSetWindowPos(windowHandle, winX, winY);
|
||||
|
||||
|
||||
int[] x2 = new int[1];
|
||||
int[] y2 = new int[1];
|
||||
int[] w2 = new int[1];
|
||||
int[] h2 = new int[1];
|
||||
glfwGetWindowFrameSize(windowHandle, x2, y2, w2, h2);
|
||||
glfwSetWindowSize(windowHandle, windowWidth - x2[0] - w2[0], windowHeight - y2[0] - h2[0]);
|
||||
|
||||
|
||||
ImageIO.setUseCache(false);
|
||||
BufferedImage[] windowIcons = null;
|
||||
|
||||
|
||||
try {
|
||||
windowIcons = new BufferedImage[] {
|
||||
ImageIO.read(new File("icon16.png")),
|
||||
ImageIO.read(new File("icon32.png"))
|
||||
};
|
||||
}catch(IOException t) {
|
||||
} catch (IOException t) {
|
||||
logger.error("Could not load default window icons!");
|
||||
logger.error(t);
|
||||
}
|
||||
|
||||
if(windowIcons != null) {
|
||||
try(MemoryStack st = MemoryStack.stackPush()) {
|
||||
|
||||
if (windowIcons != null) {
|
||||
try (MemoryStack st = MemoryStack.stackPush()) {
|
||||
GLFWImage.Buffer windowIconsBuffer = GLFWImage.malloc(windowIcons.length, st);
|
||||
|
||||
for(int i = 0; i < windowIcons.length; ++i) {
|
||||
|
||||
for (int i = 0; i < windowIcons.length; ++i) {
|
||||
int w = windowIcons[i].getWidth();
|
||||
int h = windowIcons[i].getHeight();
|
||||
|
||||
|
||||
int[] px = new int[w * h];
|
||||
windowIcons[i].getRGB(0, 0, w, h, px, 0, w);
|
||||
|
||||
for(int j = 0; j < px.length; ++j) {
|
||||
|
||||
for (int j = 0; j < px.length; ++j) {
|
||||
px[j] = (px[j] & 0xFF00FF00) | ((px[j] >> 16) & 0xFF) | ((px[j] & 0xFF) << 16); // swap R/B
|
||||
}
|
||||
|
||||
|
||||
java.nio.ByteBuffer iconBuffer = st.malloc(w * h * 4);
|
||||
iconBuffer.asIntBuffer().put(px);
|
||||
iconBuffer.flip();
|
||||
|
||||
|
||||
windowIconsBuffer.position(i);
|
||||
windowIconsBuffer.width(w);
|
||||
windowIconsBuffer.height(h);
|
||||
windowIconsBuffer.pixels(iconBuffer);
|
||||
}
|
||||
|
||||
|
||||
glfwSetWindowIcon(windowHandle, windowIconsBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long glfw_eglHandle = glfwGetEGLDisplay();
|
||||
logger.info("EGL Version: {}", eglQueryString(glfw_eglHandle, EGL_VERSION));
|
||||
|
||||
|
||||
int[] major = new int[] { 1 };
|
||||
int[] minor = new int[] { 4 };
|
||||
if(!eglInitialize(glfw_eglHandle, major, minor)) {
|
||||
if (!eglInitialize(glfw_eglHandle, major, minor)) {
|
||||
throw new RuntimeException("Could not initialize EGL");
|
||||
}
|
||||
|
||||
|
||||
EGL.createDisplayCapabilities(glfw_eglHandle, major[0], minor[0]);
|
||||
glfwMakeContextCurrent(windowHandle);
|
||||
PlatformOpenGL.setCurrentContext(GLES.createCapabilities());
|
||||
|
||||
|
||||
logger.info("OpenGL Version: {}", (glVersion = GLES30.glGetString(GLES30.GL_VERSION)));
|
||||
logger.info("OpenGL Renderer: {}", (glRenderer = GLES30.glGetString(GLES30.GL_RENDERER)));
|
||||
|
||||
|
||||
rendererANGLEPlatform = EnumPlatformANGLE.fromGLRendererString(glRenderer);
|
||||
|
||||
if(requestedANGLEPlatform != EnumPlatformANGLE.DEFAULT
|
||||
|
||||
if (requestedANGLEPlatform != EnumPlatformANGLE.DEFAULT
|
||||
&& rendererANGLEPlatform != requestedANGLEPlatform) {
|
||||
logger.warn("Incorrect ANGLE Platform: {}", rendererANGLEPlatform.name);
|
||||
}
|
||||
|
||||
if(requestedANGLEPlatform == EnumPlatformANGLE.DEFAULT) {
|
||||
|
||||
if (requestedANGLEPlatform == EnumPlatformANGLE.DEFAULT) {
|
||||
logger.info("ANGLE Platform: {}", rendererANGLEPlatform.name);
|
||||
}
|
||||
|
||||
|
||||
glfwSwapInterval(0);
|
||||
|
||||
|
||||
KHRDebug.glDebugMessageCallbackKHR(new GLDebugMessageKHRCallbackI() {
|
||||
@Override
|
||||
public void invoke(int source, int type, int id, int severity, int length, long message, long userParam) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("[KHR DEBUG #"); b.append(id); b.append("] ");
|
||||
b.append("[KHR DEBUG #");
|
||||
b.append(id);
|
||||
b.append("] ");
|
||||
|
||||
switch(source) {
|
||||
case KHRDebug.GL_DEBUG_SOURCE_API_KHR: b.append("[API - "); break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_APPLICATION_KHR: b.append("[APPLICATION - "); break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_SHADER_COMPILER_KHR: b.append("[SHADER COMPILER - "); break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_THIRD_PARTY_KHR: b.append("[THIRD PARTY - "); break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_OTHER_KHR: default: b.append("[OTHER - "); break;
|
||||
switch (source) {
|
||||
case KHRDebug.GL_DEBUG_SOURCE_API_KHR:
|
||||
b.append("[API - ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_APPLICATION_KHR:
|
||||
b.append("[APPLICATION - ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_SHADER_COMPILER_KHR:
|
||||
b.append("[SHADER COMPILER - ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_THIRD_PARTY_KHR:
|
||||
b.append("[THIRD PARTY - ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_SOURCE_OTHER_KHR:
|
||||
default:
|
||||
b.append("[OTHER - ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case KHRDebug.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR: b.append("DEPRECATED BEHAVIOR] "); break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_ERROR_KHR: b.append("ERROR] "); break;
|
||||
default:
|
||||
case KHRDebug.GL_DEBUG_TYPE_OTHER_KHR: b.append("OTHER] "); break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_PERFORMANCE_KHR: b.append("PERFORMANCE] "); break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_PORTABILITY_KHR: b.append("PORTABILITY] "); break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR: b.append("UNDEFINED BEHAVIOR] "); break;
|
||||
switch (type) {
|
||||
case KHRDebug.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR:
|
||||
b.append("DEPRECATED BEHAVIOR] ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_ERROR_KHR:
|
||||
b.append("ERROR] ");
|
||||
break;
|
||||
default:
|
||||
case KHRDebug.GL_DEBUG_TYPE_OTHER_KHR:
|
||||
b.append("OTHER] ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_PERFORMANCE_KHR:
|
||||
b.append("PERFORMANCE] ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_PORTABILITY_KHR:
|
||||
b.append("PORTABILITY] ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR:
|
||||
b.append("UNDEFINED BEHAVIOR] ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch(severity) {
|
||||
default:
|
||||
case KHRDebug.GL_DEBUG_SEVERITY_LOW_KHR: b.append("[LOW Severity] "); break;
|
||||
case KHRDebug.GL_DEBUG_SEVERITY_MEDIUM_KHR: b.append("[MEDIUM Severity] "); break;
|
||||
case KHRDebug.GL_DEBUG_SEVERITY_HIGH_KHR: b.append("[SEVERE] "); break;
|
||||
switch (severity) {
|
||||
default:
|
||||
case KHRDebug.GL_DEBUG_SEVERITY_LOW_KHR:
|
||||
b.append("[LOW Severity] ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_SEVERITY_MEDIUM_KHR:
|
||||
b.append("[MEDIUM Severity] ");
|
||||
break;
|
||||
case KHRDebug.GL_DEBUG_SEVERITY_HIGH_KHR:
|
||||
b.append("[SEVERE] ");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
String message2 = GLDebugMessageKHRCallback.getMessage(length, message);
|
||||
if(message2.contains("GPU stall due to ReadPixels")) return;
|
||||
if (message2.contains("GPU stall due to ReadPixels"))
|
||||
return;
|
||||
b.append(message2);
|
||||
logger.error(b.toString());
|
||||
|
||||
StackTraceElement[] ex = new RuntimeException().getStackTrace();
|
||||
for(int i = 0; i < ex.length; ++i) {
|
||||
for (int i = 0; i < ex.length; ++i) {
|
||||
logger.error(" at {}", ex[i]);
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +273,7 @@ public class PlatformRuntime {
|
|||
|
||||
GLES30.glEnable(KHRDebug.GL_DEBUG_OUTPUT_KHR);
|
||||
GLES30.glEnable(KHRDebug.GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
||||
|
||||
|
||||
logger.info("Initializing Audio...");
|
||||
PlatformAudio.platformInitialize();
|
||||
|
||||
|
@ -242,7 +281,7 @@ public class PlatformRuntime {
|
|||
PlatformInput.initHooks(windowHandle);
|
||||
PlatformApplication.initHooks(windowHandle);
|
||||
}
|
||||
|
||||
|
||||
public static void destroy() {
|
||||
PlatformAudio.platformShutdown();
|
||||
PlatformFilesystem.platformShutdown();
|
||||
|
@ -259,22 +298,22 @@ public class PlatformRuntime {
|
|||
public static EnumPlatformAgent getPlatformAgent() {
|
||||
return EnumPlatformAgent.DESKTOP;
|
||||
}
|
||||
|
||||
|
||||
public static String getUserAgentString() {
|
||||
return "Desktop/" + System.getProperty("os.name");
|
||||
}
|
||||
|
||||
private static EnumPlatformOS currentPlatformOS = null;
|
||||
|
||||
|
||||
public static EnumPlatformOS getPlatformOS() {
|
||||
if(currentPlatformOS == null) {
|
||||
if (currentPlatformOS == null) {
|
||||
currentPlatformOS = EnumPlatformOS.getFromJVM(System.getProperty("os.name"));
|
||||
}
|
||||
return currentPlatformOS;
|
||||
}
|
||||
|
||||
|
||||
private static EnumPlatformANGLE requestedANGLEPlatform = EnumPlatformANGLE.DEFAULT;
|
||||
|
||||
|
||||
public static void requestANGLE(EnumPlatformANGLE plaf) {
|
||||
requestedANGLEPlatform = plaf;
|
||||
}
|
||||
|
@ -282,22 +321,23 @@ public class PlatformRuntime {
|
|||
public static EnumPlatformANGLE getPlatformANGLE() {
|
||||
return rendererANGLEPlatform;
|
||||
}
|
||||
|
||||
|
||||
public static String getGLVersion() {
|
||||
return glVersion;
|
||||
}
|
||||
|
||||
|
||||
public static String getGLRenderer() {
|
||||
return glRenderer;
|
||||
}
|
||||
|
||||
public static ByteBuffer allocateByteBuffer(int length) {
|
||||
return EaglerLWJGLAllocator.allocByteBuffer(length);
|
||||
}
|
||||
|
||||
|
||||
public static IntBuffer allocateIntBuffer(int length) {
|
||||
return EaglerLWJGLAllocator.allocIntBuffer(length);
|
||||
}
|
||||
|
||||
|
||||
public static FloatBuffer allocateFloatBuffer(int length) {
|
||||
return EaglerLWJGLAllocator.allocFloatBuffer(length);
|
||||
}
|
||||
|
@ -337,102 +377,102 @@ public class PlatformRuntime {
|
|||
public static void freeFloatBuffer(FloatBuffer floatBuffer) {
|
||||
EaglerLWJGLAllocator.freeFloatBuffer(floatBuffer);
|
||||
}
|
||||
|
||||
|
||||
public static class NativeNIO {
|
||||
|
||||
|
||||
public static java.nio.ByteBuffer allocateByteBuffer(int length) {
|
||||
long ret = JEmalloc.nje_malloc(length);
|
||||
if(ret == 0l) {
|
||||
if (ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memByteBuffer(ret, length);
|
||||
}
|
||||
|
||||
|
||||
public static java.nio.IntBuffer allocateIntBuffer(int length) {
|
||||
long ret = JEmalloc.nje_malloc(length << 2);
|
||||
if(ret == 0l) {
|
||||
if (ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memIntBuffer(ret, length);
|
||||
}
|
||||
|
||||
|
||||
public static java.nio.FloatBuffer allocateFloatBuffer(int length) {
|
||||
long ret = JEmalloc.nje_malloc(length << 2);
|
||||
if(ret == 0l) {
|
||||
if (ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memFloatBuffer(ret, length);
|
||||
}
|
||||
|
||||
|
||||
public static java.nio.IntBuffer getIntBuffer(java.nio.ByteBuffer byteBuffer) {
|
||||
return MemoryUtil.memIntBuffer(MemoryUtil.memAddress(byteBuffer), byteBuffer.capacity() >> 2);
|
||||
}
|
||||
|
||||
|
||||
public static java.nio.FloatBuffer getFloatBuffer(java.nio.ByteBuffer byteBuffer) {
|
||||
return MemoryUtil.memFloatBuffer(MemoryUtil.memAddress(byteBuffer), byteBuffer.capacity() >> 2);
|
||||
}
|
||||
|
||||
|
||||
public static java.nio.ByteBuffer getAsByteBuffer(java.nio.IntBuffer intBuffer) {
|
||||
return MemoryUtil.memByteBuffer(MemoryUtil.memAddress(intBuffer), intBuffer.capacity() << 2);
|
||||
}
|
||||
|
||||
|
||||
public static java.nio.ByteBuffer getAsByteBuffer(java.nio.FloatBuffer floatBuffer) {
|
||||
return MemoryUtil.memByteBuffer(MemoryUtil.memAddress(floatBuffer), floatBuffer.capacity() << 2);
|
||||
}
|
||||
|
||||
|
||||
public static void freeByteBuffer(java.nio.ByteBuffer byteBuffer) {
|
||||
JEmalloc.nje_free(MemoryUtil.memAddress(byteBuffer));
|
||||
}
|
||||
|
||||
|
||||
public static void freeIntBuffer(java.nio.IntBuffer intBuffer) {
|
||||
JEmalloc.nje_free(MemoryUtil.memAddress(intBuffer));
|
||||
}
|
||||
|
||||
|
||||
public static void freeFloatBuffer(java.nio.FloatBuffer floatBuffer) {
|
||||
JEmalloc.nje_free(MemoryUtil.memAddress(floatBuffer));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static boolean isDebugRuntime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static void writeCrashReport(String crashDump) {
|
||||
File file1 = new File("./crash-reports");
|
||||
if(!file1.exists()) {
|
||||
if(!file1.mkdirs()) {
|
||||
if (!file1.exists()) {
|
||||
if (!file1.mkdirs()) {
|
||||
PlatformRuntime.logger.fatal("Could not create crash report directory: {}", file1.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
File file2 = new File(file1,
|
||||
"crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-client.txt");
|
||||
try(FileOutputStream os = new FileOutputStream(file2)) {
|
||||
try (FileOutputStream os = new FileOutputStream(file2)) {
|
||||
os.write(crashDump.getBytes(StandardCharsets.UTF_8));
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
PlatformRuntime.logger.fatal("Could not write crash report: {}", file2.getAbsolutePath());
|
||||
PlatformRuntime.logger.fatal(ex);
|
||||
return;
|
||||
}
|
||||
PlatformRuntime.logger.fatal("Crash report was written to: {}", file2.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
public static void getStackTrace(Throwable t, Consumer<String> ret) {
|
||||
StackTraceElement[] stackTrace = t.getStackTrace();
|
||||
for(int i = 0; i < stackTrace.length; ++i) {
|
||||
for (int i = 0; i < stackTrace.length; ++i) {
|
||||
ret.accept(stackTrace[i].toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean printJSExceptionIfBrowser(Throwable t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static void exit() {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
||||
public static void setThreadName(String string) {
|
||||
Thread.currentThread().setName(string);
|
||||
}
|
||||
|
@ -448,53 +488,53 @@ public class PlatformRuntime {
|
|||
public static long freeMemory() {
|
||||
return Runtime.getRuntime().freeMemory();
|
||||
}
|
||||
|
||||
|
||||
public static String getCallingClass(int backTrace) {
|
||||
StackTraceElement[] astacktraceelement = Thread.currentThread().getStackTrace();
|
||||
StackTraceElement stacktraceelement = astacktraceelement[Math.min(backTrace + 1, astacktraceelement.length)];
|
||||
return "" + stacktraceelement.getFileName() + ":" + stacktraceelement.getLineNumber();
|
||||
}
|
||||
|
||||
|
||||
public static OutputStream newDeflaterOutputStream(OutputStream os) throws IOException {
|
||||
return new DeflaterOutputStream(os);
|
||||
}
|
||||
|
||||
|
||||
public static OutputStream newGZIPOutputStream(OutputStream os) throws IOException {
|
||||
return new GZIPOutputStream(os);
|
||||
}
|
||||
|
||||
|
||||
public static InputStream newInflaterInputStream(InputStream is) throws IOException {
|
||||
return new InflaterInputStream(is);
|
||||
}
|
||||
|
||||
|
||||
public static InputStream newGZIPInputStream(InputStream is) throws IOException {
|
||||
return new GZIPInputStream(is);
|
||||
}
|
||||
|
||||
|
||||
public static void downloadRemoteURIByteArray(String assetPackageURI, final Consumer<byte[]> cb) {
|
||||
logger.info("Downloading: {}");
|
||||
try(InputStream is = (new URL(assetPackageURI)).openStream()) {
|
||||
try (InputStream is = (new URL(assetPackageURI)).openStream()) {
|
||||
EaglerOutputStream bao = new EaglerOutputStream();
|
||||
byte[] copyBuffer = new byte[16384];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
while ((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
bao.write(copyBuffer, 0, i);
|
||||
}
|
||||
cb.accept(bao.toByteArray());
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Failed to download file!");
|
||||
logger.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean requireSSL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isOfflineDownloadURL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static IClientConfigAdapter getClientConfigAdapter() {
|
||||
return DesktopClientConfigAdapter.instance;
|
||||
}
|
||||
|
@ -514,7 +554,7 @@ public class PlatformRuntime {
|
|||
private static final Random seedProvider = new Random();
|
||||
|
||||
public static long randomSeed() {
|
||||
synchronized(seedProvider) {
|
||||
synchronized (seedProvider) {
|
||||
return seedProvider.nextLong();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,16 +13,24 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -30,7 +38,7 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
|||
class WebSocketPlayClient extends WebSocketClient {
|
||||
|
||||
private static final Draft perMessageDeflateDraft = new Draft_6455(new PerMessageDeflateExtension());
|
||||
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("WebSocket");
|
||||
|
||||
WebSocketPlayClient(URI serverUri) {
|
||||
|
@ -60,10 +68,10 @@ class WebSocketPlayClient extends WebSocketClient {
|
|||
|
||||
@Override
|
||||
public void onMessage(String arg0) {
|
||||
if(arg0.equalsIgnoreCase("BLOCKED")) {
|
||||
if (arg0.equalsIgnoreCase("BLOCKED")) {
|
||||
logger.error("Reached full IP ratelimit!");
|
||||
PlatformNetworking.serverRateLimit = EnumServerRateLimit.BLOCKED;
|
||||
}else if(arg0.equalsIgnoreCase("LOCKED")) {
|
||||
} else if (arg0.equalsIgnoreCase("LOCKED")) {
|
||||
logger.error("Reached full IP ratelimit lockout!");
|
||||
PlatformNetworking.serverRateLimit = EnumServerRateLimit.LOCKED_OUT;
|
||||
}
|
||||
|
@ -73,5 +81,5 @@ class WebSocketPlayClient extends WebSocketClient {
|
|||
public void onMessage(ByteBuffer arg0) {
|
||||
PlatformNetworking.recievedPlayPacket(arg0.array());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,16 +16,24 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -55,17 +63,17 @@ class WebSocketServerQuery extends WebSocketClient implements IServerQuery {
|
|||
|
||||
@Override
|
||||
public int responsesAvailable() {
|
||||
synchronized(queryResponses) {
|
||||
synchronized (queryResponses) {
|
||||
return queryResponses.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResponse getResponse() {
|
||||
synchronized(queryResponses) {
|
||||
if(queryResponses.size() > 0) {
|
||||
synchronized (queryResponses) {
|
||||
if (queryResponses.size() > 0) {
|
||||
return queryResponses.remove(0);
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -73,17 +81,17 @@ class WebSocketServerQuery extends WebSocketClient implements IServerQuery {
|
|||
|
||||
@Override
|
||||
public int binaryResponsesAvailable() {
|
||||
synchronized(queryResponsesBytes) {
|
||||
synchronized (queryResponsesBytes) {
|
||||
return queryResponsesBytes.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBinaryResponse() {
|
||||
synchronized(queryResponsesBytes) {
|
||||
if(queryResponsesBytes.size() > 0) {
|
||||
synchronized (queryResponsesBytes) {
|
||||
if (queryResponsesBytes.size() > 0) {
|
||||
return queryResponsesBytes.remove(0);
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -114,38 +122,39 @@ class WebSocketServerQuery extends WebSocketClient implements IServerQuery {
|
|||
@Override
|
||||
public void onMessage(String arg0) {
|
||||
alive = true;
|
||||
if(pingTimer == -1) {
|
||||
if (pingTimer == -1) {
|
||||
pingTimer = System.currentTimeMillis() - pingStart;
|
||||
if(pingTimer < 1) {
|
||||
if (pingTimer < 1) {
|
||||
pingTimer = 1;
|
||||
}
|
||||
}
|
||||
if(arg0.equalsIgnoreCase("BLOCKED")) {
|
||||
if (arg0.equalsIgnoreCase("BLOCKED")) {
|
||||
logger.error("Reached full IP ratelimit for {}!", this.uri.toString());
|
||||
rateLimit = EnumServerRateLimit.BLOCKED;
|
||||
return;
|
||||
}
|
||||
if(arg0.equalsIgnoreCase("LOCKED")) {
|
||||
if (arg0.equalsIgnoreCase("LOCKED")) {
|
||||
logger.error("Reached full IP ratelimit lockout for {}!", this.uri.toString());
|
||||
rateLimit = EnumServerRateLimit.LOCKED_OUT;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
JSONObject obj = new JSONObject(arg0);
|
||||
if("blocked".equalsIgnoreCase(obj.optString("type", null))) {
|
||||
if ("blocked".equalsIgnoreCase(obj.optString("type", null))) {
|
||||
logger.error("Reached query ratelimit for {}!", this.uri.toString());
|
||||
rateLimit = EnumServerRateLimit.BLOCKED;
|
||||
}else if("locked".equalsIgnoreCase(obj.optString("type", null))) {
|
||||
} else if ("locked".equalsIgnoreCase(obj.optString("type", null))) {
|
||||
logger.error("Reached query ratelimit lockout for {}!", this.uri.toString());
|
||||
rateLimit = EnumServerRateLimit.LOCKED_OUT;
|
||||
}else {
|
||||
} else {
|
||||
QueryResponse response = new QueryResponse(obj, pingTimer);
|
||||
synchronized(queryResponses) {
|
||||
synchronized (queryResponses) {
|
||||
queryResponses.add(response);
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
logger.error("Exception thrown parsing websocket query response from \"" + this.getURI().toString() + "\"!");
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
"Exception thrown parsing websocket query response from \"" + this.getURI().toString() + "\"!");
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
|
@ -153,13 +162,13 @@ class WebSocketServerQuery extends WebSocketClient implements IServerQuery {
|
|||
@Override
|
||||
public void onMessage(ByteBuffer arg0) {
|
||||
alive = true;
|
||||
if(pingTimer == -1) {
|
||||
if (pingTimer == -1) {
|
||||
pingTimer = System.currentTimeMillis() - pingStart;
|
||||
if(pingTimer < 1) {
|
||||
if (pingTimer < 1) {
|
||||
pingTimer = 1;
|
||||
}
|
||||
}
|
||||
synchronized(queryResponsesBytes) {
|
||||
synchronized (queryResponsesBytes) {
|
||||
queryResponsesBytes.add(arg0.array());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,16 +10,24 @@ import net.lax1dude.eaglercraft.v1_8.sp.server.internal.lwjgl.DesktopIntegratedS
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.server.internal.lwjgl.MemoryConnection;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -33,14 +41,14 @@ public class ClientPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static void sendPacket(IPCPacketData packet) {
|
||||
synchronized(MemoryConnection.clientToServerQueue) {
|
||||
synchronized (MemoryConnection.clientToServerQueue) {
|
||||
MemoryConnection.clientToServerQueue.add(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static IPCPacketData recievePacket() {
|
||||
synchronized(MemoryConnection.serverToClientQueue) {
|
||||
if(MemoryConnection.serverToClientQueue.size() > 0) {
|
||||
synchronized (MemoryConnection.serverToClientQueue) {
|
||||
if (MemoryConnection.serverToClientQueue.size() > 0) {
|
||||
return MemoryConnection.serverToClientQueue.remove(0);
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +56,10 @@ public class ClientPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static List<IPCPacketData> recieveAllPacket() {
|
||||
synchronized(MemoryConnection.serverToClientQueue) {
|
||||
if(MemoryConnection.serverToClientQueue.size() == 0) {
|
||||
synchronized (MemoryConnection.serverToClientQueue) {
|
||||
if (MemoryConnection.serverToClientQueue.size() == 0) {
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
List<IPCPacketData> ret = new ArrayList(MemoryConnection.serverToClientQueue);
|
||||
MemoryConnection.serverToClientQueue.clear();
|
||||
return ret;
|
||||
|
@ -72,7 +80,7 @@ public class ClientPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static void showCrashReportOverlay(String report, int x, int y, int w, int h) {
|
||||
if(crashOverlay == null) {
|
||||
if (crashOverlay == null) {
|
||||
crashOverlay = new CrashScreenPopup();
|
||||
}
|
||||
int[] wx = new int[1];
|
||||
|
|
|
@ -10,16 +10,24 @@ import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.DesktopClientConfigAdapter;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.server.internal.lwjgl.MemoryConnection;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -31,14 +39,14 @@ public class ServerPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static void sendPacket(IPCPacketData packet) {
|
||||
synchronized(MemoryConnection.serverToClientQueue) {
|
||||
synchronized (MemoryConnection.serverToClientQueue) {
|
||||
MemoryConnection.serverToClientQueue.add(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static IPCPacketData recievePacket() {
|
||||
synchronized(MemoryConnection.clientToServerQueue) {
|
||||
if(MemoryConnection.clientToServerQueue.size() > 0) {
|
||||
synchronized (MemoryConnection.clientToServerQueue) {
|
||||
if (MemoryConnection.clientToServerQueue.size() > 0) {
|
||||
return MemoryConnection.clientToServerQueue.remove(0);
|
||||
}
|
||||
}
|
||||
|
@ -46,10 +54,10 @@ public class ServerPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static List<IPCPacketData> recieveAllPacket() {
|
||||
synchronized(MemoryConnection.clientToServerQueue) {
|
||||
if(MemoryConnection.clientToServerQueue.size() == 0) {
|
||||
synchronized (MemoryConnection.clientToServerQueue) {
|
||||
if (MemoryConnection.clientToServerQueue.size() == 0) {
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
List<IPCPacketData> ret = new ArrayList(MemoryConnection.clientToServerQueue);
|
||||
MemoryConnection.clientToServerQueue.clear();
|
||||
return ret;
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8;
|
|||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -24,7 +32,7 @@ public class Display {
|
|||
public static int getWidth() {
|
||||
return PlatformInput.getWindowWidth();
|
||||
}
|
||||
|
||||
|
||||
public static int getHeight() {
|
||||
return PlatformInput.getWindowHeight();
|
||||
}
|
||||
|
@ -34,11 +42,11 @@ public class Display {
|
|||
}
|
||||
|
||||
public static void create() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void setTitle(String string) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static boolean isCloseRequested() {
|
||||
|
@ -55,22 +63,22 @@ public class Display {
|
|||
|
||||
public static void sync(int limitFramerate) {
|
||||
boolean limitFPS = limitFramerate > 0 && limitFramerate < 1000;
|
||||
|
||||
if(limitFPS) {
|
||||
|
||||
if (limitFPS) {
|
||||
long millis = System.currentTimeMillis();
|
||||
long frameMillis = (1000l / limitFramerate) - (millis - lastSwap);
|
||||
if(frameMillis > 0l) {
|
||||
if (frameMillis > 0l) {
|
||||
EagUtils.sleep(frameMillis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lastSwap = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static boolean contextLost() {
|
||||
return PlatformInput.contextLost();
|
||||
}
|
||||
|
||||
|
||||
public static boolean wasResized() {
|
||||
return PlatformInput.wasResized();
|
||||
}
|
||||
|
|
|
@ -29,16 +29,24 @@ import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
|||
import net.lax1dude.eaglercraft.v1_8.update.UpdateService;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -53,11 +61,11 @@ public class EagRuntime {
|
|||
private static String userAgentString = null;
|
||||
private static EnumPlatformOS operatingSystem = null;
|
||||
private static EnumPlatformANGLE angleBackend = null;
|
||||
|
||||
|
||||
public static String getVersion() {
|
||||
return "EagRuntimeX 1.0";
|
||||
}
|
||||
|
||||
|
||||
public static void create() {
|
||||
logger.info("Version: {}", getVersion());
|
||||
PlatformRuntime.create();
|
||||
|
@ -119,40 +127,40 @@ public class EagRuntime {
|
|||
public static void freeFloatBuffer(FloatBuffer byteBuffer) {
|
||||
PlatformRuntime.freeFloatBuffer(byteBuffer);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getResourceBytes(String path) {
|
||||
return PlatformAssets.getResourceBytes(path);
|
||||
}
|
||||
|
||||
|
||||
public static InputStream getResourceStream(String path) {
|
||||
byte[] b = PlatformAssets.getResourceBytes(path);
|
||||
if(b != null) {
|
||||
if (b != null) {
|
||||
return new EaglerInputStream(b);
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getResourceString(String path) {
|
||||
byte[] bytes = PlatformAssets.getResourceBytes(path);
|
||||
return bytes != null ? new String(bytes, StandardCharsets.UTF_8) : null;
|
||||
}
|
||||
|
||||
|
||||
public static List<String> getResourceLines(String path) {
|
||||
byte[] bytes = PlatformAssets.getResourceBytes(path);
|
||||
if(bytes != null) {
|
||||
if (bytes != null) {
|
||||
List<String> ret = new ArrayList();
|
||||
try {
|
||||
BufferedReader rd = new BufferedReader(new StringReader(path));
|
||||
String s;
|
||||
while((s = rd.readLine()) != null) {
|
||||
while ((s = rd.readLine()) != null) {
|
||||
ret.add(s);
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
// ??
|
||||
}
|
||||
return ret;
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +168,7 @@ public class EagRuntime {
|
|||
public static void debugPrintStackTraceToSTDERR(Throwable t) {
|
||||
debugPrintStackTraceToSTDERR0("", t);
|
||||
Throwable c = t.getCause();
|
||||
while(c != null) {
|
||||
while (c != null) {
|
||||
debugPrintStackTraceToSTDERR0("Caused by: ", c);
|
||||
c = c.getCause();
|
||||
}
|
||||
|
@ -168,17 +176,17 @@ public class EagRuntime {
|
|||
|
||||
private static void debugPrintStackTraceToSTDERR0(String pfx, Throwable t) {
|
||||
System.err.println(pfx + t.toString());
|
||||
if(!PlatformRuntime.printJSExceptionIfBrowser(t)) {
|
||||
if (!PlatformRuntime.printJSExceptionIfBrowser(t)) {
|
||||
getStackTrace(t, (s) -> {
|
||||
System.err.println(" at " + s);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void getStackTrace(Throwable t, Consumer<String> ret) {
|
||||
PlatformRuntime.getStackTrace(t, ret);
|
||||
}
|
||||
|
||||
|
||||
public static String[] getStackTraceElements(Throwable t) {
|
||||
List<String> lst = new ArrayList();
|
||||
PlatformRuntime.getStackTrace(t, (s) -> {
|
||||
|
@ -186,38 +194,38 @@ public class EagRuntime {
|
|||
});
|
||||
return lst.toArray(new String[lst.size()]);
|
||||
}
|
||||
|
||||
|
||||
public static String getStackTrace(Throwable t) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
getStackTrace0(t, sb);
|
||||
Throwable c = t.getCause();
|
||||
while(c != null) {
|
||||
while (c != null) {
|
||||
sb.append("\nCaused by: ");
|
||||
getStackTrace0(c, sb);
|
||||
c = c.getCause();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private static void getStackTrace0(Throwable t, StringBuilder sb) {
|
||||
sb.append(t.toString());
|
||||
getStackTrace(t, (s) -> {
|
||||
sb.append('\n').append(" at ").append(s);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static void debugPrintStackTrace(Throwable t) {
|
||||
exceptionLogger.error(t);
|
||||
}
|
||||
|
||||
|
||||
public static void dumpStack() {
|
||||
try {
|
||||
throw new Exception("Stack Trace");
|
||||
}catch(Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
exceptionLogger.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void exit() {
|
||||
PlatformRuntime.exit();
|
||||
}
|
||||
|
@ -315,7 +323,7 @@ public class EagRuntime {
|
|||
}
|
||||
|
||||
public static Calendar getLocaleCalendar() {
|
||||
return Calendar.getInstance(); //TODO: fix teavm calendar's time zone offset
|
||||
return Calendar.getInstance(); // TODO: fix teavm calendar's time zone offset
|
||||
}
|
||||
|
||||
public static <T extends DateFormat> T fixDateFormat(T input) {
|
||||
|
|
|
@ -5,28 +5,36 @@ import java.util.List;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EagUtils {
|
||||
|
||||
|
||||
private static final String hex = "0123456789ABCDEF";
|
||||
public static final Pattern splitPattern = Pattern.compile("(\\r\\n|\\n|\\r)");
|
||||
|
||||
|
||||
public static String hexString(int value, int digits) {
|
||||
String ret = "";
|
||||
for(int i = 0, l = digits << 2; i < l; i += 4) {
|
||||
for (int i = 0, l = digits << 2; i < l; i += 4) {
|
||||
ret = hex.charAt((value >> i) & 0xF) + ret;
|
||||
}
|
||||
return ret;
|
||||
|
@ -35,51 +43,51 @@ public class EagUtils {
|
|||
public static String[] linesArray(String input) {
|
||||
return splitPattern.split(input);
|
||||
}
|
||||
|
||||
|
||||
public static List<String> linesList(String input) {
|
||||
return Arrays.asList(splitPattern.split(input));
|
||||
}
|
||||
|
||||
|
||||
public static int decodeHex(CharSequence num) {
|
||||
int ret = 0;
|
||||
for(int i = 0, l = num.length(); i < l; ++i) {
|
||||
for (int i = 0, l = num.length(); i < l; ++i) {
|
||||
ret = ret << 4;
|
||||
int v = hex.indexOf(num.charAt(i));
|
||||
if(v >= 0) {
|
||||
if (v >= 0) {
|
||||
ret |= v;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static int decodeHexByte(CharSequence str, int off) {
|
||||
return str.length() < off + 2 ? decodeHex(str.subSequence(off, 2)) : 0;
|
||||
}
|
||||
|
||||
|
||||
public static void sleep(long millis) {
|
||||
try {
|
||||
Thread.sleep(millis);
|
||||
}catch(InterruptedException ex) {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String toASCIIEagler(String str) {
|
||||
char[] ascii = new char[str.length()];
|
||||
for(int i = 0; i < ascii.length; ++i) {
|
||||
int c = (int)str.charAt(i);
|
||||
if(c < 32 || c > 126) {
|
||||
for (int i = 0; i < ascii.length; ++i) {
|
||||
int c = (int) str.charAt(i);
|
||||
if (c < 32 || c > 126) {
|
||||
ascii[i] = '_';
|
||||
}else {
|
||||
ascii[i] = (char)c;
|
||||
} else {
|
||||
ascii[i] = (char) c;
|
||||
}
|
||||
}
|
||||
return new String(ascii);
|
||||
}
|
||||
|
||||
|
||||
public static void validateASCIIEagler(String str) {
|
||||
for(int i = 0, l = str.length(); i < l; ++i) {
|
||||
int c = (int)str.charAt(i);
|
||||
if(c < 32 || c > 126) {
|
||||
for (int i = 0, l = str.length(); i < l; ++i) {
|
||||
int c = (int) str.charAt(i);
|
||||
if (c < 32 || c > 126) {
|
||||
throw new IllegalArgumentException("invalid ascii");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,41 +25,49 @@ import net.minecraft.util.MathHelper;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EaglercraftSoundManager {
|
||||
|
||||
|
||||
protected static class ActiveSoundEvent {
|
||||
|
||||
protected final EaglercraftSoundManager manager;
|
||||
|
||||
|
||||
protected final ISound soundInstance;
|
||||
protected final SoundCategory soundCategory;
|
||||
protected final SoundPoolEntry soundConfig;
|
||||
protected IAudioHandle soundHandle;
|
||||
|
||||
|
||||
protected float activeX;
|
||||
protected float activeY;
|
||||
protected float activeZ;
|
||||
|
||||
|
||||
protected float activePitch;
|
||||
protected float activeGain;
|
||||
|
||||
|
||||
protected int repeatCounter = 0;
|
||||
protected boolean paused = false;
|
||||
|
||||
|
||||
protected ActiveSoundEvent(EaglercraftSoundManager manager, ISound soundInstance,
|
||||
SoundCategory soundCategory, SoundPoolEntry soundConfig, IAudioHandle soundHandle) {
|
||||
this.manager = manager;
|
||||
|
@ -73,49 +81,50 @@ public class EaglercraftSoundManager {
|
|||
this.activePitch = soundInstance.getPitch();
|
||||
this.activeGain = soundInstance.getVolume();
|
||||
}
|
||||
|
||||
|
||||
protected void updateLocation() {
|
||||
float x = soundInstance.getXPosF();
|
||||
float y = soundInstance.getYPosF();
|
||||
float z = soundInstance.getZPosF();
|
||||
float pitch = soundInstance.getPitch();
|
||||
float gain = soundInstance.getVolume();
|
||||
if(x != activeX || y != activeY || z != activeZ) {
|
||||
if (x != activeX || y != activeY || z != activeZ) {
|
||||
soundHandle.move(x, y, z);
|
||||
activeX = x;
|
||||
activeY = y;
|
||||
activeZ = z;
|
||||
}
|
||||
if(pitch != activePitch) {
|
||||
soundHandle.pitch(MathHelper.clamp_float(pitch * (float)soundConfig.getPitch(), 0.5f, 2.0f));
|
||||
if (pitch != activePitch) {
|
||||
soundHandle.pitch(MathHelper.clamp_float(pitch * (float) soundConfig.getPitch(), 0.5f, 2.0f));
|
||||
activePitch = pitch;
|
||||
}
|
||||
if(gain != activeGain) {
|
||||
if (gain != activeGain) {
|
||||
float attenuatedGain = gain * manager.categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
|
||||
(soundCategory == SoundCategory.MASTER ? 1.0f : manager.categoryVolumes[soundCategory.getCategoryId()])
|
||||
* (float)soundConfig.getVolume();
|
||||
(soundCategory == SoundCategory.MASTER ? 1.0f
|
||||
: manager.categoryVolumes[soundCategory.getCategoryId()])
|
||||
* (float) soundConfig.getVolume();
|
||||
soundHandle.gain(MathHelper.clamp_float(attenuatedGain, 0.0f, 1.0f));
|
||||
activeGain = gain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected static class WaitingSoundEvent {
|
||||
|
||||
|
||||
protected final ISound playSound;
|
||||
protected int playTicks;
|
||||
protected boolean paused = false;
|
||||
|
||||
|
||||
private WaitingSoundEvent(ISound playSound, int playTicks) {
|
||||
this.playSound = playSound;
|
||||
this.playTicks = playTicks;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("SoundManager");
|
||||
|
||||
|
||||
private final GameSettings settings;
|
||||
private final SoundHandler handler;
|
||||
private final float[] categoryVolumes;
|
||||
|
@ -139,139 +148,141 @@ public class EaglercraftSoundManager {
|
|||
public void unloadSoundSystem() {
|
||||
// handled by PlatformApplication
|
||||
}
|
||||
|
||||
|
||||
public void reloadSoundSystem() {
|
||||
PlatformAudio.flushAudioCache();
|
||||
}
|
||||
|
||||
|
||||
public void setSoundCategoryVolume(SoundCategory category, float volume) {
|
||||
categoryVolumes[category.getCategoryId()] = volume;
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if((category == SoundCategory.MASTER || evt.soundCategory == category)
|
||||
if ((category == SoundCategory.MASTER || evt.soundCategory == category)
|
||||
&& !evt.soundHandle.shouldFree()) {
|
||||
float newVolume = (evt.activeGain = evt.soundInstance.getVolume()) * categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
|
||||
(evt.soundCategory == SoundCategory.MASTER ? 1.0f : categoryVolumes[evt.soundCategory.getCategoryId()])
|
||||
* (float)evt.soundConfig.getVolume();
|
||||
float newVolume = (evt.activeGain = evt.soundInstance.getVolume())
|
||||
* categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
|
||||
(evt.soundCategory == SoundCategory.MASTER ? 1.0f
|
||||
: categoryVolumes[evt.soundCategory.getCategoryId()])
|
||||
* (float) evt.soundConfig.getVolume();
|
||||
newVolume = MathHelper.clamp_float(newVolume, 0.0f, 1.0f);
|
||||
if(newVolume > 0.0f) {
|
||||
if (newVolume > 0.0f) {
|
||||
evt.soundHandle.gain(newVolume);
|
||||
}else {
|
||||
} else {
|
||||
evt.soundHandle.end();
|
||||
soundItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopAllSounds() {
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if(!evt.soundHandle.shouldFree()) {
|
||||
if (!evt.soundHandle.shouldFree()) {
|
||||
evt.soundHandle.end();
|
||||
}
|
||||
}
|
||||
activeSounds.clear();
|
||||
}
|
||||
|
||||
|
||||
public void pauseAllSounds() {
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if(!evt.soundHandle.shouldFree()) {
|
||||
if (!evt.soundHandle.shouldFree()) {
|
||||
evt.soundHandle.pause(true);
|
||||
evt.paused = true;
|
||||
}
|
||||
}
|
||||
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
|
||||
while(soundItr2.hasNext()) {
|
||||
while (soundItr2.hasNext()) {
|
||||
soundItr2.next().paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void resumeAllSounds() {
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if(!evt.soundHandle.shouldFree()) {
|
||||
if (!evt.soundHandle.shouldFree()) {
|
||||
evt.soundHandle.pause(false);
|
||||
evt.paused = false;
|
||||
}
|
||||
}
|
||||
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
|
||||
while(soundItr2.hasNext()) {
|
||||
while (soundItr2.hasNext()) {
|
||||
soundItr2.next().paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateAllSounds() {
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if(!evt.paused && (evt.soundInstance instanceof ITickable)) {
|
||||
if (!evt.paused && (evt.soundInstance instanceof ITickable)) {
|
||||
boolean destroy = false;
|
||||
try {
|
||||
((ITickable)evt.soundInstance).update();
|
||||
((ITickable) evt.soundInstance).update();
|
||||
if ((evt.soundInstance instanceof ITickableSound)
|
||||
&& ((ITickableSound) evt.soundInstance).isDonePlaying()) {
|
||||
destroy = true;
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Error ticking sound: {}", t.toString());
|
||||
logger.error(t);
|
||||
destroy = true;
|
||||
}
|
||||
if(destroy) {
|
||||
if(!evt.soundHandle.shouldFree()) {
|
||||
if (destroy) {
|
||||
if (!evt.soundHandle.shouldFree()) {
|
||||
evt.soundHandle.end();
|
||||
}
|
||||
soundItr.remove();
|
||||
}
|
||||
}
|
||||
if(evt.soundHandle.shouldFree()) {
|
||||
if(evt.soundInstance.canRepeat()) {
|
||||
if(!evt.paused && ++evt.repeatCounter > evt.soundInstance.getRepeatDelay()) {
|
||||
if (evt.soundHandle.shouldFree()) {
|
||||
if (evt.soundInstance.canRepeat()) {
|
||||
if (!evt.paused && ++evt.repeatCounter > evt.soundInstance.getRepeatDelay()) {
|
||||
evt.repeatCounter = 0;
|
||||
evt.updateLocation();
|
||||
evt.soundHandle.restart();
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
soundItr.remove();
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
evt.updateLocation();
|
||||
}
|
||||
}
|
||||
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
|
||||
while(soundItr2.hasNext()) {
|
||||
while (soundItr2.hasNext()) {
|
||||
WaitingSoundEvent evt = soundItr2.next();
|
||||
if(!evt.paused && --evt.playTicks <= 0) {
|
||||
if (!evt.paused && --evt.playTicks <= 0) {
|
||||
soundItr2.remove();
|
||||
playSound(evt.playSound);
|
||||
}
|
||||
}
|
||||
PlatformAudio.clearAudioCache();
|
||||
}
|
||||
|
||||
|
||||
public boolean isSoundPlaying(ISound sound) {
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if(evt.soundInstance == sound) {
|
||||
if (evt.soundInstance == sound) {
|
||||
return !evt.soundHandle.shouldFree();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void stopSound(ISound sound) {
|
||||
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
|
||||
while(soundItr.hasNext()) {
|
||||
while (soundItr.hasNext()) {
|
||||
ActiveSoundEvent evt = soundItr.next();
|
||||
if(evt.soundInstance == sound) {
|
||||
if(!evt.soundHandle.shouldFree()) {
|
||||
if (evt.soundInstance == sound) {
|
||||
if (!evt.soundHandle.shouldFree()) {
|
||||
evt.soundHandle.end();
|
||||
soundItr.remove();
|
||||
return;
|
||||
|
@ -279,8 +290,8 @@ public class EaglercraftSoundManager {
|
|||
}
|
||||
}
|
||||
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
|
||||
while(soundItr2.hasNext()) {
|
||||
if(soundItr2.next().playSound == sound) {
|
||||
while (soundItr2.hasNext()) {
|
||||
if (soundItr2.next().playSound == sound) {
|
||||
soundItr2.remove();
|
||||
}
|
||||
}
|
||||
|
@ -290,54 +301,59 @@ public class EaglercraftSoundManager {
|
|||
try {
|
||||
return EaglerInputStream.inputStreamToBytesQuiet(Minecraft.getMinecraft().getResourceManager()
|
||||
.getResource(new ResourceLocation(filename)).getInputStream());
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public void playSound(ISound sound) {
|
||||
if(!PlatformAudio.available()) {
|
||||
if (!PlatformAudio.available()) {
|
||||
return;
|
||||
}
|
||||
if(sound != null && categoryVolumes[SoundCategory.MASTER.getCategoryId()] > 0.0f) {
|
||||
if (sound != null && categoryVolumes[SoundCategory.MASTER.getCategoryId()] > 0.0f) {
|
||||
SoundEventAccessorComposite accessor = handler.getSound(sound.getSoundLocation());
|
||||
if(accessor == null) {
|
||||
if (accessor == null) {
|
||||
logger.warn("Unable to play unknown soundEvent(1): {}", sound.getSoundLocation().toString());
|
||||
}else {
|
||||
} else {
|
||||
SoundPoolEntry etr = accessor.cloneEntry();
|
||||
if (etr == SoundHandler.missing_sound) {
|
||||
logger.warn("Unable to play empty soundEvent(2): {}", etr.getSoundPoolEntryLocation().toString());
|
||||
}else {
|
||||
} else {
|
||||
ResourceLocation lc = etr.getSoundPoolEntryLocation();
|
||||
IAudioResource trk;
|
||||
if(EagRuntime.getPlatformType() != EnumPlatformType.DESKTOP) {
|
||||
trk = PlatformAudio.loadAudioDataNew(lc.toString(), !etr.isStreamingSound(), browserResourcePackLoader);
|
||||
}else {
|
||||
if (EagRuntime.getPlatformType() != EnumPlatformType.DESKTOP) {
|
||||
trk = PlatformAudio.loadAudioDataNew(lc.toString(), !etr.isStreamingSound(),
|
||||
browserResourcePackLoader);
|
||||
} else {
|
||||
trk = PlatformAudio.loadAudioData(
|
||||
"/assets/" + lc.getResourceDomain() + "/" + lc.getResourcePath(), !etr.isStreamingSound());
|
||||
"/assets/" + lc.getResourceDomain() + "/" + lc.getResourcePath(),
|
||||
!etr.isStreamingSound());
|
||||
}
|
||||
if(trk == null) {
|
||||
if (trk == null) {
|
||||
logger.warn("Unable to play unknown soundEvent(3): {}", sound.getSoundLocation().toString());
|
||||
}else {
|
||||
|
||||
ActiveSoundEvent newSound = new ActiveSoundEvent(this, sound, accessor.getSoundCategory(), etr, null);
|
||||
} else {
|
||||
|
||||
ActiveSoundEvent newSound = new ActiveSoundEvent(this, sound, accessor.getSoundCategory(), etr,
|
||||
null);
|
||||
|
||||
float pitch = MathHelper.clamp_float(newSound.activePitch * (float) etr.getPitch(), 0.5f, 2.0f);
|
||||
float attenuatedGain = newSound.activeGain
|
||||
* categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
|
||||
(accessor.getSoundCategory() == SoundCategory.MASTER ? 1.0f
|
||||
: categoryVolumes[accessor.getSoundCategory().getCategoryId()])
|
||||
* (float) etr.getVolume();
|
||||
|
||||
float pitch = MathHelper.clamp_float(newSound.activePitch * (float)etr.getPitch(), 0.5f, 2.0f);
|
||||
float attenuatedGain = newSound.activeGain * categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
|
||||
(accessor.getSoundCategory() == SoundCategory.MASTER ? 1.0f :
|
||||
categoryVolumes[accessor.getSoundCategory().getCategoryId()]) * (float)etr.getVolume();
|
||||
|
||||
AttenuationType tp = sound.getAttenuationType();
|
||||
if(tp == AttenuationType.LINEAR) {
|
||||
if (tp == AttenuationType.LINEAR) {
|
||||
newSound.soundHandle = PlatformAudio.beginPlayback(trk, newSound.activeX, newSound.activeY,
|
||||
newSound.activeZ, attenuatedGain, pitch);
|
||||
}else {
|
||||
} else {
|
||||
newSound.soundHandle = PlatformAudio.beginPlaybackStatic(trk, attenuatedGain, pitch);
|
||||
}
|
||||
|
||||
if(newSound.soundHandle == null) {
|
||||
|
||||
if (newSound.soundHandle == null) {
|
||||
logger.error("Unable to play soundEvent(4): {}", sound.getSoundLocation().toString());
|
||||
}else {
|
||||
} else {
|
||||
activeSounds.add(newSound);
|
||||
}
|
||||
}
|
||||
|
@ -345,28 +361,29 @@ public class EaglercraftSoundManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void playDelayedSound(ISound sound, int delay) {
|
||||
queuedSounds.add(new WaitingSoundEvent(sound, delay));
|
||||
}
|
||||
|
||||
|
||||
public void setListener(EntityPlayer player, float partialTicks) {
|
||||
if(!PlatformAudio.available()) {
|
||||
if (!PlatformAudio.available()) {
|
||||
return;
|
||||
}
|
||||
if(player != null) {
|
||||
if (player != null) {
|
||||
try {
|
||||
float f = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * partialTicks;
|
||||
float f1 = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * partialTicks;
|
||||
double d0 = player.prevPosX + (player.posX - player.prevPosX) * (double) partialTicks;
|
||||
double d1 = player.prevPosY + (player.posY - player.prevPosY) * (double) partialTicks + (double) player.getEyeHeight();
|
||||
double d1 = player.prevPosY + (player.posY - player.prevPosY) * (double) partialTicks
|
||||
+ (double) player.getEyeHeight();
|
||||
double d2 = player.prevPosZ + (player.posZ - player.prevPosZ) * (double) partialTicks;
|
||||
PlatformAudio.setListener((float)d0, (float)d1, (float)d2, f, f1);
|
||||
}catch(Throwable t) {
|
||||
PlatformAudio.setListener((float) d0, (float) d1, (float) d2, f, f1);
|
||||
} catch (Throwable t) {
|
||||
// eaglercraft 1.5.2 had Infinity/NaN crashes for this function which
|
||||
// couldn't be resolved via if statement checks in the above variables
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,22 +4,30 @@ import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants;
|
|||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class Keyboard {
|
||||
|
||||
|
||||
public static void enableRepeatEvents(boolean b) {
|
||||
PlatformInput.keyboardEnableRepeatEvents(b);
|
||||
}
|
||||
|
|
|
@ -6,16 +6,24 @@ import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
|
|||
import net.lax1dude.eaglercraft.v1_8.internal.RenderResolution;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -29,11 +37,11 @@ public class Mouse {
|
|||
}
|
||||
|
||||
public static int getX() {
|
||||
return (int)(PlatformInput.mouseGetX());
|
||||
return (int) (PlatformInput.mouseGetX());
|
||||
}
|
||||
|
||||
public static int getY() {
|
||||
return (int)(PlatformInput.mouseGetY());
|
||||
return (int) (PlatformInput.mouseGetY());
|
||||
}
|
||||
|
||||
public static boolean getEventButtonState() {
|
||||
|
@ -49,11 +57,11 @@ public class Mouse {
|
|||
}
|
||||
|
||||
public static int getEventX() {
|
||||
return (int)(PlatformInput.mouseGetEventX());
|
||||
return (int) (PlatformInput.mouseGetEventX());
|
||||
}
|
||||
|
||||
public static int getEventY() {
|
||||
return (int)(PlatformInput.mouseGetEventY());
|
||||
return (int) (PlatformInput.mouseGetEventY());
|
||||
}
|
||||
|
||||
public static int getEventButton() {
|
||||
|
@ -100,9 +108,9 @@ public class Mouse {
|
|||
private static EnumCursorType currentCursorType = EnumCursorType.DEFAULT;
|
||||
|
||||
public static void showCursor(EnumCursorType cursor) {
|
||||
if(EagRuntime.getConfiguration().useSpecialCursors()) {
|
||||
if (EagRuntime.getConfiguration().useSpecialCursors()) {
|
||||
customCursorCounter = 2;
|
||||
if(currentCursorType != cursor) {
|
||||
if (currentCursorType != cursor) {
|
||||
PlatformInput.showCursor(cursor);
|
||||
currentCursorType = cursor;
|
||||
}
|
||||
|
@ -110,10 +118,10 @@ public class Mouse {
|
|||
}
|
||||
|
||||
public static void tickCursorShape() {
|
||||
if(EagRuntime.getConfiguration().useSpecialCursors()) {
|
||||
if(customCursorCounter > 0) {
|
||||
if(--customCursorCounter == 0) {
|
||||
if(currentCursorType != EnumCursorType.DEFAULT) {
|
||||
if (EagRuntime.getConfiguration().useSpecialCursors()) {
|
||||
if (customCursorCounter > 0) {
|
||||
if (--customCursorCounter == 0) {
|
||||
if (currentCursorType != EnumCursorType.DEFAULT) {
|
||||
PlatformInput.showCursor(EnumCursorType.DEFAULT);
|
||||
currentCursorType = EnumCursorType.DEFAULT;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.cache;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -4,16 +4,24 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -30,7 +38,7 @@ public class EaglerLoadingCache<K, V> {
|
|||
|
||||
public V get(K key) {
|
||||
V etr = cacheMap.get(key);
|
||||
if(etr == null) {
|
||||
if (etr == null) {
|
||||
etr = provider.create(key);
|
||||
cacheMap.put(key, etr);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.futures;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -18,7 +26,7 @@ package net.lax1dude.eaglercraft.v1_8.futures;
|
|||
public class CancellationException extends IllegalStateException {
|
||||
|
||||
public CancellationException() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public CancellationException(String s) {
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.futures;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8.futures;
|
|||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8.futures;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -4,16 +4,24 @@ import java.util.concurrent.Callable;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -24,16 +32,16 @@ public class FutureTask<V> implements RunnableFuture<V> {
|
|||
private boolean completed;
|
||||
private V result;
|
||||
private Callable<V> callable;
|
||||
|
||||
|
||||
public FutureTask(Callable<V> callable) {
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
if(!cancelled) {
|
||||
if (!cancelled) {
|
||||
cancelled = true;
|
||||
if(!completed) {
|
||||
if (!completed) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
@ -52,13 +60,13 @@ public class FutureTask<V> implements RunnableFuture<V> {
|
|||
|
||||
@Override
|
||||
public V get() throws InterruptedException, ExecutionException {
|
||||
if(!completed) {
|
||||
if(!cancelled) {
|
||||
if (!completed) {
|
||||
if (!cancelled) {
|
||||
try {
|
||||
result = callable.call();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new ExecutionException(t);
|
||||
}finally {
|
||||
} finally {
|
||||
completed = true;
|
||||
done();
|
||||
}
|
||||
|
@ -82,8 +90,8 @@ public class FutureTask<V> implements RunnableFuture<V> {
|
|||
throw new ExecutionException(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void done() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -11,16 +11,24 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -6,22 +6,30 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public interface ListenableFuture<V> extends Future<V> {
|
||||
|
||||
|
||||
static final Logger futureExceptionLogger = LogManager.getLogger("ListenableFuture");
|
||||
|
||||
void addListener(Runnable listener, Executor executor);
|
||||
|
|
|
@ -6,22 +6,30 @@ import java.util.concurrent.Callable;
|
|||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class ListenableFutureTask<V> extends FutureTask<V> implements ListenableFuture<V> {
|
||||
|
||||
|
||||
private final List<Runnable> listeners = new ArrayList();
|
||||
|
||||
public ListenableFutureTask(Callable<V> callable) {
|
||||
|
@ -36,16 +44,16 @@ public class ListenableFutureTask<V> extends FutureTask<V> implements Listenable
|
|||
public void run() {
|
||||
executor.execute(listener); // so dumb
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected void done() {
|
||||
for(int i = 0, l = listeners.size(); i < l; ++i) {
|
||||
for (int i = 0, l = listeners.size(); i < l; ++i) {
|
||||
Runnable r = listeners.get(i);
|
||||
try {
|
||||
r.run();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
ListenableFuture.futureExceptionLogger.error("Exception caught running future listener!");
|
||||
ListenableFuture.futureExceptionLogger.error(t);
|
||||
}
|
||||
|
@ -56,5 +64,5 @@ public class ListenableFutureTask<V> extends FutureTask<V> implements Listenable
|
|||
public static <V> ListenableFutureTask<V> create(Callable<V> callableToSchedule) {
|
||||
return new ListenableFutureTask(callableToSchedule);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.futures;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -23,16 +23,24 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
|||
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -46,14 +54,21 @@ public class EaglercraftGPU {
|
|||
static final Logger logger = LogManager.getLogger("EaglercraftGPU");
|
||||
|
||||
public static final String gluErrorString(int i) {
|
||||
switch(i) {
|
||||
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
|
||||
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
|
||||
case 1286: return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
|
||||
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
|
||||
case GL_CONTEXT_LOST_WEBGL: return "CONTEXT_LOST_WEBGL";
|
||||
default: return "Unknown Error";
|
||||
switch (i) {
|
||||
case GL_INVALID_ENUM:
|
||||
return "GL_INVALID_ENUM";
|
||||
case GL_INVALID_VALUE:
|
||||
return "GL_INVALID_VALUE";
|
||||
case 1286:
|
||||
return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
case GL_INVALID_OPERATION:
|
||||
return "GL_INVALID_OPERATION";
|
||||
case GL_OUT_OF_MEMORY:
|
||||
return "GL_OUT_OF_MEMORY";
|
||||
case GL_CONTEXT_LOST_WEBGL:
|
||||
return "CONTEXT_LOST_WEBGL";
|
||||
default:
|
||||
return "Unknown Error";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,34 +83,34 @@ public class EaglercraftGPU {
|
|||
public static final void glCopyTexSubImage2D(int target, int level, int sx, int sy, int dx, int dy, int w, int h) {
|
||||
_wglCopyTexSubImage2D(target, level, sx, sy, dx, dy, w, h);
|
||||
}
|
||||
|
||||
|
||||
private static DisplayList currentList = null;
|
||||
private static ByteBuffer displayListBuffer = EagRuntime.allocateByteBuffer(0x100000);
|
||||
|
||||
public static final void glNewList(int target, int op) {
|
||||
if(currentList != null) {
|
||||
if (currentList != null) {
|
||||
throw new IllegalStateException("A display list is already being compiled you eagler!");
|
||||
}
|
||||
if(op != GL_COMPILE) {
|
||||
if (op != GL_COMPILE) {
|
||||
throw new UnsupportedOperationException("Only GL_COMPILE is supported by glNewList");
|
||||
}
|
||||
DisplayList dp = currentList = mapDisplayListsGL.get(target);
|
||||
if(dp == null) {
|
||||
if (dp == null) {
|
||||
throw new IllegalArgumentException("Unknown display list: " + target);
|
||||
}
|
||||
if(dp.vertexArray != null && dp.attribs > 0) {
|
||||
if (dp.vertexArray != null && dp.attribs > 0) {
|
||||
EaglercraftGPU.bindGLBufferArray(dp.vertexArray);
|
||||
int c = 0;
|
||||
if((dp.attribs & ATTRIB_TEXTURE) == ATTRIB_TEXTURE) {
|
||||
if ((dp.attribs & ATTRIB_TEXTURE) == ATTRIB_TEXTURE) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
}
|
||||
if((dp.attribs & ATTRIB_COLOR) == ATTRIB_COLOR) {
|
||||
if ((dp.attribs & ATTRIB_COLOR) == ATTRIB_COLOR) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
}
|
||||
if((dp.attribs & ATTRIB_NORMAL) == ATTRIB_NORMAL) {
|
||||
if ((dp.attribs & ATTRIB_NORMAL) == ATTRIB_NORMAL) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
}
|
||||
if((dp.attribs & ATTRIB_LIGHTMAP) == ATTRIB_LIGHTMAP) {
|
||||
if ((dp.attribs & ATTRIB_LIGHTMAP) == ATTRIB_LIGHTMAP) {
|
||||
_wglDisableVertexAttribArray(++c);
|
||||
}
|
||||
}
|
||||
|
@ -103,13 +118,13 @@ public class EaglercraftGPU {
|
|||
dp.mode = -1;
|
||||
dp.count = 0;
|
||||
}
|
||||
|
||||
|
||||
private static final void growDisplayListBuffer(int len) {
|
||||
int wantSize = displayListBuffer.position() + len;
|
||||
if(displayListBuffer.capacity() < wantSize) {
|
||||
if (displayListBuffer.capacity() < wantSize) {
|
||||
int newSize = (wantSize & 0xFFFE0000) + 0x40000;
|
||||
ByteBuffer newBuffer = EagRuntime.allocateByteBuffer(newSize);
|
||||
PlatformBufferFunctions.put(newBuffer, (ByteBuffer)displayListBuffer.flip());
|
||||
PlatformBufferFunctions.put(newBuffer, (ByteBuffer) displayListBuffer.flip());
|
||||
EagRuntime.freeByteBuffer(displayListBuffer);
|
||||
displayListBuffer = newBuffer;
|
||||
}
|
||||
|
@ -117,87 +132,87 @@ public class EaglercraftGPU {
|
|||
|
||||
public static final void glEndList() {
|
||||
DisplayList dp = currentList;
|
||||
if(dp == null) {
|
||||
if (dp == null) {
|
||||
throw new IllegalStateException("No list is currently being compiled!");
|
||||
}
|
||||
|
||||
if(dp.attribs == -1) {
|
||||
if(dp.vertexArray != null) {
|
||||
|
||||
if (dp.attribs == -1) {
|
||||
if (dp.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(dp.vertexArray);
|
||||
dp.vertexArray = null;
|
||||
}
|
||||
if(dp.vertexBuffer != null) {
|
||||
if (dp.vertexBuffer != null) {
|
||||
_wglDeleteBuffers(dp.vertexBuffer);
|
||||
dp.vertexBuffer = null;
|
||||
}
|
||||
currentList = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if(dp.vertexArray == null) {
|
||||
|
||||
if (dp.vertexArray == null) {
|
||||
dp.vertexArray = _wglGenVertexArrays();
|
||||
dp.bindQuad16 = false;
|
||||
dp.bindQuad32 = false;
|
||||
}
|
||||
if(dp.vertexBuffer == null) {
|
||||
if (dp.vertexBuffer == null) {
|
||||
dp.vertexBuffer = _wglGenBuffers();
|
||||
}
|
||||
|
||||
|
||||
bindGLArrayBuffer(dp.vertexBuffer);
|
||||
displayListBuffer.flip();
|
||||
_wglBufferData(GL_ARRAY_BUFFER, displayListBuffer, GL_STATIC_DRAW);
|
||||
displayListBuffer.clear();
|
||||
|
||||
|
||||
FixedFunctionPipeline.setupDisplayList(dp);
|
||||
currentList = null;
|
||||
}
|
||||
|
||||
public static final void glCallList(int displayList) {
|
||||
DisplayList dp = mapDisplayListsGL.get(displayList);
|
||||
if(dp == null) {
|
||||
if (dp == null) {
|
||||
throw new NullPointerException("Tried to call a display list that does not exist: " + displayList);
|
||||
}
|
||||
if(dp.attribs != -1) {
|
||||
if (dp.attribs != -1) {
|
||||
FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(dp.attribs).update();
|
||||
bindGLBufferArray(dp.vertexArray);
|
||||
if(dp.mode == GL_QUADS) {
|
||||
if (dp.mode == GL_QUADS) {
|
||||
int cnt = dp.count;
|
||||
if(cnt > 0xFFFF) {
|
||||
if(!dp.bindQuad32) {
|
||||
if (cnt > 0xFFFF) {
|
||||
if (!dp.bindQuad32) {
|
||||
dp.bindQuad16 = false;
|
||||
dp.bindQuad32 = true;
|
||||
attachQuad32EmulationBuffer(cnt, true);
|
||||
}else {
|
||||
} else {
|
||||
attachQuad32EmulationBuffer(cnt, false);
|
||||
}
|
||||
p.drawElements(GL_TRIANGLES, cnt + (cnt >> 1), GL_UNSIGNED_INT, 0);
|
||||
}else {
|
||||
if(!dp.bindQuad16) {
|
||||
} else {
|
||||
if (!dp.bindQuad16) {
|
||||
dp.bindQuad16 = true;
|
||||
dp.bindQuad32 = false;
|
||||
attachQuad16EmulationBuffer(cnt, true);
|
||||
}else {
|
||||
} else {
|
||||
attachQuad16EmulationBuffer(cnt, false);
|
||||
}
|
||||
p.drawElements(GL_TRIANGLES, cnt + (cnt >> 1), GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
p.drawArrays(dp.mode, 0, dp.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final void flushDisplayList(int displayList) {
|
||||
DisplayList dp = mapDisplayListsGL.get(displayList);
|
||||
if(dp == null) {
|
||||
if (dp == null) {
|
||||
throw new NullPointerException("Tried to flush a display list that does not exist: " + displayList);
|
||||
}
|
||||
dp.attribs = -1;
|
||||
if(dp.vertexArray != null) {
|
||||
if (dp.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(dp.vertexArray);
|
||||
dp.vertexArray = null;
|
||||
}
|
||||
if(dp.vertexBuffer != null) {
|
||||
if (dp.vertexBuffer != null) {
|
||||
_wglDeleteBuffers(dp.vertexBuffer);
|
||||
dp.vertexBuffer = null;
|
||||
}
|
||||
|
@ -209,12 +224,12 @@ public class EaglercraftGPU {
|
|||
GlStateManager.stateNormalZ = z;
|
||||
++GlStateManager.stateNormalSerial;
|
||||
}
|
||||
|
||||
private static final Map<Integer,String> stringCache = new HashMap();
|
||||
|
||||
private static final Map<Integer, String> stringCache = new HashMap();
|
||||
|
||||
public static final String glGetString(int param) {
|
||||
String str = stringCache.get(param);
|
||||
if(str == null) {
|
||||
if (str == null) {
|
||||
str = _wglGetString(param);
|
||||
stringCache.put(param, str);
|
||||
}
|
||||
|
@ -222,15 +237,15 @@ public class EaglercraftGPU {
|
|||
}
|
||||
|
||||
public static final void glGetInteger(int param, int[] values) {
|
||||
switch(param) {
|
||||
case GL_VIEWPORT:
|
||||
values[0] = GlStateManager.viewportX;
|
||||
values[1] = GlStateManager.viewportY;
|
||||
values[2] = GlStateManager.viewportW;
|
||||
values[3] = GlStateManager.viewportH;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("glGetInteger only accepts GL_VIEWPORT as a parameter");
|
||||
switch (param) {
|
||||
case GL_VIEWPORT:
|
||||
values[0] = GlStateManager.viewportX;
|
||||
values[1] = GlStateManager.viewportY;
|
||||
values[2] = GlStateManager.viewportW;
|
||||
values[3] = GlStateManager.viewportH;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("glGetInteger only accepts GL_VIEWPORT as a parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,23 +266,23 @@ public class EaglercraftGPU {
|
|||
public static final void glTexStorage2D(int target, int levels, int internalFormat, int w, int h) {
|
||||
_wglTexStorage2D(target, levels, internalFormat, w, h);
|
||||
}
|
||||
|
||||
|
||||
public static final void glLineWidth(float f) {
|
||||
_wglLineWidth(f);
|
||||
}
|
||||
|
||||
public static final void glFog(int param, FloatBuffer valueBuffer) {
|
||||
int pos = valueBuffer.position();
|
||||
switch(param) {
|
||||
case GL_FOG_COLOR:
|
||||
GlStateManager.stateFogColorR = valueBuffer.get();
|
||||
GlStateManager.stateFogColorG = valueBuffer.get();
|
||||
GlStateManager.stateFogColorB = valueBuffer.get();
|
||||
GlStateManager.stateFogColorA = valueBuffer.get();
|
||||
++GlStateManager.stateFogSerial;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Only GL_FOG_COLOR is configurable!");
|
||||
switch (param) {
|
||||
case GL_FOG_COLOR:
|
||||
GlStateManager.stateFogColorR = valueBuffer.get();
|
||||
GlStateManager.stateFogColorG = valueBuffer.get();
|
||||
GlStateManager.stateFogColorB = valueBuffer.get();
|
||||
GlStateManager.stateFogColorA = valueBuffer.get();
|
||||
++GlStateManager.stateFogSerial;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Only GL_FOG_COLOR is configurable!");
|
||||
}
|
||||
valueBuffer.position(pos);
|
||||
}
|
||||
|
@ -282,11 +297,11 @@ public class EaglercraftGPU {
|
|||
|
||||
public static final void glDeleteLists(int id) {
|
||||
DisplayList d = mapDisplayListsGL.free(id);
|
||||
if(d != null) {
|
||||
if(d.vertexArray != null) {
|
||||
if (d != null) {
|
||||
if (d.vertexArray != null) {
|
||||
_wglDeleteVertexArrays(d.vertexArray);
|
||||
}
|
||||
if(d.vertexBuffer != null) {
|
||||
if (d.vertexBuffer != null) {
|
||||
_wglDeleteBuffers(d.vertexBuffer);
|
||||
}
|
||||
}
|
||||
|
@ -297,54 +312,54 @@ public class EaglercraftGPU {
|
|||
}
|
||||
|
||||
public static final void glBlendEquation(int equation) {
|
||||
if(equation != GlStateManager.stateBlendEquation) {
|
||||
if (equation != GlStateManager.stateBlendEquation) {
|
||||
_wglBlendEquation(equation);
|
||||
GlStateManager.stateBlendEquation = equation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static IBufferArrayGL currentBufferArray = null;
|
||||
|
||||
|
||||
public static final void bindGLBufferArray(IBufferArrayGL buffer) {
|
||||
if(currentBufferArray != buffer) {
|
||||
if (currentBufferArray != buffer) {
|
||||
_wglBindVertexArray(buffer);
|
||||
currentBufferArray = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static IBufferGL currentArrayBuffer = null;
|
||||
|
||||
|
||||
public static final void bindGLArrayBuffer(IBufferGL buffer) {
|
||||
if(currentArrayBuffer != buffer) {
|
||||
if (currentArrayBuffer != buffer) {
|
||||
_wglBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
currentArrayBuffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static IBufferGL currentUniformBuffer = null;
|
||||
|
||||
|
||||
public static final void bindGLUniformBuffer(IBufferGL buffer) {
|
||||
if(currentUniformBuffer != buffer) {
|
||||
if (currentUniformBuffer != buffer) {
|
||||
_wglBindBuffer(0x8A11, buffer);
|
||||
currentUniformBuffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static IProgramGL currentShaderProgram = null;
|
||||
|
||||
|
||||
public static final void bindGLShaderProgram(IProgramGL prog) {
|
||||
if(currentShaderProgram != prog) {
|
||||
if (currentShaderProgram != prog) {
|
||||
_wglUseProgram(prog);
|
||||
currentShaderProgram = prog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final IBufferGL[] currentUniformBlockBindings = new IBufferGL[16];
|
||||
private static final int[] currentUniformBlockBindingOffset = new int[16];
|
||||
private static final int[] currentUniformBlockBindingSize = new int[16];
|
||||
|
||||
|
||||
public static final void bindUniformBufferRange(int index, IBufferGL buffer, int offset, int size) {
|
||||
if(currentUniformBlockBindings[index] != buffer || currentUniformBlockBindingOffset[index] != offset
|
||||
if (currentUniformBlockBindings[index] != buffer || currentUniformBlockBindingOffset[index] != offset
|
||||
|| currentUniformBlockBindingSize[index] != size) {
|
||||
_wglBindBufferRange(0x8A11, index, buffer, offset, size);
|
||||
currentUniformBlockBindings[index] = buffer;
|
||||
|
@ -352,31 +367,32 @@ public class EaglercraftGPU {
|
|||
currentUniformBlockBindingSize[index] = size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final int ATTRIB_TEXTURE = 1;
|
||||
public static final int ATTRIB_COLOR = 2;
|
||||
public static final int ATTRIB_NORMAL = 4;
|
||||
public static final int ATTRIB_LIGHTMAP = 8;
|
||||
|
||||
|
||||
public static final void renderBuffer(ByteBuffer buffer, int attrib, int mode, int count) {
|
||||
if(currentList != null) {
|
||||
if(currentList.attribs == -1) {
|
||||
if (currentList != null) {
|
||||
if (currentList.attribs == -1) {
|
||||
currentList.attribs = attrib;
|
||||
}else if(currentList.attribs != attrib) {
|
||||
throw new UnsupportedOperationException("Inconsistent vertex format in display list (only one is allowed)");
|
||||
} else if (currentList.attribs != attrib) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Inconsistent vertex format in display list (only one is allowed)");
|
||||
}
|
||||
if(currentList.mode == -1) {
|
||||
if (currentList.mode == -1) {
|
||||
currentList.mode = mode;
|
||||
}else if(currentList.mode != mode) {
|
||||
} else if (currentList.mode != mode) {
|
||||
throw new UnsupportedOperationException("Inconsistent draw mode in display list (only one is allowed)");
|
||||
}
|
||||
currentList.count += count;
|
||||
if(buffer.remaining() > displayListBuffer.remaining()) {
|
||||
if (buffer.remaining() > displayListBuffer.remaining()) {
|
||||
growDisplayListBuffer(buffer.remaining());
|
||||
}
|
||||
displayListBuffer.put(buffer);
|
||||
lastRender = null;
|
||||
}else {
|
||||
} else {
|
||||
lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib).update();
|
||||
lastRender.drawDirectArrays(mode, 0, count);
|
||||
lastMode = mode;
|
||||
|
@ -393,8 +409,9 @@ public class EaglercraftGPU {
|
|||
private static int lastCount = 0;
|
||||
|
||||
public static final void renderAgain() {
|
||||
if(lastRender == null) {
|
||||
throw new UnsupportedOperationException("Cannot render the same verticies twice while generating display list");
|
||||
if (lastRender == null) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot render the same verticies twice while generating display list");
|
||||
}
|
||||
EaglercraftGPU.bindGLBufferArray(lastRender.getDirectModeBufferArray());
|
||||
lastRender.update().drawDirectArrays(lastMode, 0, lastCount);
|
||||
|
@ -402,58 +419,58 @@ public class EaglercraftGPU {
|
|||
|
||||
private static IBufferGL quad16EmulationBuffer = null;
|
||||
private static int quad16EmulationBufferSize = 0;
|
||||
|
||||
|
||||
private static IBufferGL quad32EmulationBuffer = null;
|
||||
private static int quad32EmulationBufferSize = 0;
|
||||
|
||||
|
||||
public static final void attachQuad16EmulationBuffer(int vertexCount, boolean bind) {
|
||||
IBufferGL buf = quad16EmulationBuffer;
|
||||
if(buf == null) {
|
||||
if (buf == null) {
|
||||
quad16EmulationBuffer = buf = _wglGenBuffers();
|
||||
int newSize = quad16EmulationBufferSize = (vertexCount & 0xFFFFF000) + 0x2000;
|
||||
if(newSize > 0xFFFF) {
|
||||
if (newSize > 0xFFFF) {
|
||||
newSize = 0xFFFF;
|
||||
}
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
resizeQuad16EmulationBuffer(newSize >> 2);
|
||||
}else {
|
||||
} else {
|
||||
int cnt = quad16EmulationBufferSize;
|
||||
if(cnt < vertexCount) {
|
||||
if (cnt < vertexCount) {
|
||||
int newSize = quad16EmulationBufferSize = (vertexCount & 0xFFFFF000) + 0x2000;
|
||||
if(newSize > 0xFFFF) {
|
||||
if (newSize > 0xFFFF) {
|
||||
newSize = 0xFFFF;
|
||||
}
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
resizeQuad16EmulationBuffer(newSize >> 2);
|
||||
}else if(bind) {
|
||||
} else if (bind) {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final void attachQuad32EmulationBuffer(int vertexCount, boolean bind) {
|
||||
IBufferGL buf = quad32EmulationBuffer;
|
||||
if(buf == null) {
|
||||
if (buf == null) {
|
||||
quad32EmulationBuffer = buf = _wglGenBuffers();
|
||||
int newSize = quad32EmulationBufferSize = (vertexCount & 0xFFFFC000) + 0x8000;
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
resizeQuad32EmulationBuffer(newSize >> 2);
|
||||
}else {
|
||||
} else {
|
||||
int cnt = quad32EmulationBufferSize;
|
||||
if(cnt < vertexCount) {
|
||||
if (cnt < vertexCount) {
|
||||
int newSize = quad32EmulationBufferSize = (vertexCount & 0xFFFFC000) + 0x8000;
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
resizeQuad32EmulationBuffer(newSize >> 2);
|
||||
}else if(bind) {
|
||||
} else if (bind) {
|
||||
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final void resizeQuad16EmulationBuffer(int quadCount) {
|
||||
IntBuffer buf = EagRuntime.allocateIntBuffer(quadCount * 3);
|
||||
int v1, v2, v3, v4;
|
||||
for(int i = 0; i < quadCount; ++i) {
|
||||
for (int i = 0; i < quadCount; ++i) {
|
||||
v1 = i << 2;
|
||||
v2 = v1 + 1;
|
||||
v3 = v2 + 1;
|
||||
|
@ -466,18 +483,21 @@ public class EaglercraftGPU {
|
|||
_wglBufferData(GL_ELEMENT_ARRAY_BUFFER, buf, GL_STATIC_DRAW);
|
||||
EagRuntime.freeIntBuffer(buf);
|
||||
}
|
||||
|
||||
|
||||
private static final void resizeQuad32EmulationBuffer(int quadCount) {
|
||||
IntBuffer buf = EagRuntime.allocateIntBuffer(quadCount * 6);
|
||||
int v1, v2, v3, v4;
|
||||
for(int i = 0; i < quadCount; ++i) {
|
||||
for (int i = 0; i < quadCount; ++i) {
|
||||
v1 = i << 2;
|
||||
v2 = v1 + 1;
|
||||
v3 = v2 + 1;
|
||||
v4 = v3 + 1;
|
||||
buf.put(v1); buf.put(v2);
|
||||
buf.put(v4); buf.put(v2);
|
||||
buf.put(v3); buf.put(v4);
|
||||
buf.put(v1);
|
||||
buf.put(v2);
|
||||
buf.put(v4);
|
||||
buf.put(v2);
|
||||
buf.put(v3);
|
||||
buf.put(v4);
|
||||
}
|
||||
buf.flip();
|
||||
_wglBufferData(GL_ELEMENT_ARRAY_BUFFER, buf, GL_STATIC_DRAW);
|
||||
|
@ -489,7 +509,7 @@ public class EaglercraftGPU {
|
|||
}
|
||||
|
||||
public static final void drawHighPoly(HighPolyMesh mesh) {
|
||||
if(mesh.vertexCount == 0 || mesh.indexCount == 0 || mesh.vertexArray == null) {
|
||||
if (mesh.vertexCount == 0 || mesh.indexCount == 0 || mesh.vertexArray == null) {
|
||||
return;
|
||||
}
|
||||
FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update();
|
||||
|
@ -501,80 +521,92 @@ public class EaglercraftGPU {
|
|||
static boolean hasFramebufferHDR32FSupport = false;
|
||||
static boolean hasLinearHDR32FSupport = false;
|
||||
|
||||
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback) {
|
||||
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format,
|
||||
boolean allow32bitFallback) {
|
||||
createFramebufferHDR16FTexture(target, level, w, h, format, allow32bitFallback, null);
|
||||
}
|
||||
|
||||
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
|
||||
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format,
|
||||
ByteBuffer pixelData) {
|
||||
createFramebufferHDR16FTexture(target, level, w, h, format, false, pixelData);
|
||||
}
|
||||
|
||||
private static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback, ByteBuffer pixelData) {
|
||||
if(hasFramebufferHDR16FSupport) {
|
||||
private static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format,
|
||||
boolean allow32bitFallback, ByteBuffer pixelData) {
|
||||
if (hasFramebufferHDR16FSupport) {
|
||||
int internalFormat;
|
||||
switch(format) {
|
||||
case GL_RED:
|
||||
internalFormat = 0x822D; // GL_R16F
|
||||
break;
|
||||
case 0x8227: // GL_RG
|
||||
internalFormat = 0x822F; // GL_RG16F
|
||||
case GL_RGB:
|
||||
throw new UnsupportedOperationException("GL_RGB16F isn't supported specifically in WebGL 2.0 for some goddamn reason");
|
||||
case GL_RGBA:
|
||||
internalFormat = 0x881A; // GL_RGBA16F
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown format: " + format);
|
||||
switch (format) {
|
||||
case GL_RED:
|
||||
internalFormat = 0x822D; // GL_R16F
|
||||
break;
|
||||
case 0x8227: // GL_RG
|
||||
internalFormat = 0x822F; // GL_RG16F
|
||||
case GL_RGB:
|
||||
throw new UnsupportedOperationException(
|
||||
"GL_RGB16F isn't supported specifically in WebGL 2.0 for some goddamn reason");
|
||||
case GL_RGBA:
|
||||
internalFormat = 0x881A; // GL_RGBA16F
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown format: " + format);
|
||||
}
|
||||
_wglTexImage2Du16(target, level, internalFormat, w, h, 0, format, 0x140B, pixelData);
|
||||
}else {
|
||||
if(allow32bitFallback) {
|
||||
if(hasFramebufferHDR32FSupport) {
|
||||
} else {
|
||||
if (allow32bitFallback) {
|
||||
if (hasFramebufferHDR32FSupport) {
|
||||
createFramebufferHDR32FTexture(target, level, w, h, format, false, null);
|
||||
}else {
|
||||
throw new UnsupportedOperationException("No fallback 32-bit HDR (floating point) texture support is available on this device");
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
"No fallback 32-bit HDR (floating point) texture support is available on this device");
|
||||
}
|
||||
}else {
|
||||
throw new UnsupportedOperationException("16-bit HDR (floating point) textures are not supported on this device");
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
"16-bit HDR (floating point) textures are not supported on this device");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback) {
|
||||
public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format,
|
||||
boolean allow16bitFallback) {
|
||||
createFramebufferHDR32FTexture(target, level, w, h, format, allow16bitFallback, null);
|
||||
}
|
||||
|
||||
public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
|
||||
public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format,
|
||||
ByteBuffer pixelData) {
|
||||
createFramebufferHDR32FTexture(target, level, w, h, format, false, pixelData);
|
||||
}
|
||||
|
||||
private static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback, ByteBuffer pixelData) {
|
||||
if(hasFramebufferHDR32FSupport) {
|
||||
private static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format,
|
||||
boolean allow16bitFallback, ByteBuffer pixelData) {
|
||||
if (hasFramebufferHDR32FSupport) {
|
||||
int internalFormat;
|
||||
switch(format) {
|
||||
case GL_RED:
|
||||
internalFormat = 0x822E; // GL_R32F
|
||||
break;
|
||||
case 0x8227: // GL_RG
|
||||
internalFormat = 0x822F; // GL_RG32F
|
||||
case GL_RGB:
|
||||
throw new UnsupportedOperationException("GL_RGB32F isn't supported specifically in WebGL 2.0 for some goddamn reason");
|
||||
case GL_RGBA:
|
||||
internalFormat = 0x8814; //GL_RGBA32F
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown format: " + format);
|
||||
switch (format) {
|
||||
case GL_RED:
|
||||
internalFormat = 0x822E; // GL_R32F
|
||||
break;
|
||||
case 0x8227: // GL_RG
|
||||
internalFormat = 0x822F; // GL_RG32F
|
||||
case GL_RGB:
|
||||
throw new UnsupportedOperationException(
|
||||
"GL_RGB32F isn't supported specifically in WebGL 2.0 for some goddamn reason");
|
||||
case GL_RGBA:
|
||||
internalFormat = 0x8814; // GL_RGBA32F
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown format: " + format);
|
||||
}
|
||||
_wglTexImage2Df32(target, level, internalFormat, w, h, 0, format, GL_FLOAT, pixelData);
|
||||
}else {
|
||||
if(allow16bitFallback) {
|
||||
if(hasFramebufferHDR16FSupport) {
|
||||
} else {
|
||||
if (allow16bitFallback) {
|
||||
if (hasFramebufferHDR16FSupport) {
|
||||
createFramebufferHDR16FTexture(target, level, w, h, format, false);
|
||||
}else {
|
||||
throw new UnsupportedOperationException("No fallback 16-bit HDR (floating point) texture support is available on this device");
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
"No fallback 16-bit HDR (floating point) texture support is available on this device");
|
||||
}
|
||||
}else {
|
||||
throw new UnsupportedOperationException("32-bit HDR (floating point) textures are not supported on this device");
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
"32-bit HDR (floating point) textures are not supported on this device");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,24 +616,24 @@ public class EaglercraftGPU {
|
|||
EaglercraftGPU.glGetString(7937);
|
||||
EaglercraftGPU.glGetString(7938);
|
||||
hasFramebufferHDR16FSupport = PlatformOpenGL.checkHDRFramebufferSupport(16);
|
||||
if(hasFramebufferHDR16FSupport) {
|
||||
if (hasFramebufferHDR16FSupport) {
|
||||
logger.info("16-bit HDR render target support: true");
|
||||
}else {
|
||||
} else {
|
||||
logger.error("16-bit HDR render target support: false");
|
||||
}
|
||||
hasFramebufferHDR32FSupport = PlatformOpenGL.checkHDRFramebufferSupport(32);
|
||||
if(hasFramebufferHDR32FSupport) {
|
||||
if (hasFramebufferHDR32FSupport) {
|
||||
logger.info("32-bit HDR render target support: true");
|
||||
}else {
|
||||
} else {
|
||||
logger.error("32-bit HDR render target support: false");
|
||||
}
|
||||
hasLinearHDR32FSupport = PlatformOpenGL.checkLinearHDR32FSupport();
|
||||
if(hasLinearHDR32FSupport) {
|
||||
if (hasLinearHDR32FSupport) {
|
||||
logger.info("32-bit HDR linear filter support: true");
|
||||
}else {
|
||||
} else {
|
||||
logger.error("32-bit HDR linear filter support: false");
|
||||
}
|
||||
if(!checkHasHDRFramebufferSupportWithFilter()) {
|
||||
if (!checkHasHDRFramebufferSupportWithFilter()) {
|
||||
logger.error("No HDR render target support was detected! Shaders will be disabled.");
|
||||
}
|
||||
DrawUtils.init();
|
||||
|
@ -615,13 +647,13 @@ public class EaglercraftGPU {
|
|||
}
|
||||
|
||||
public static final boolean checkHDRFramebufferSupport(int bits) {
|
||||
switch(bits) {
|
||||
case 16:
|
||||
return hasFramebufferHDR16FSupport;
|
||||
case 32:
|
||||
return hasFramebufferHDR32FSupport;
|
||||
default:
|
||||
return false;
|
||||
switch (bits) {
|
||||
case 16:
|
||||
return hasFramebufferHDR16FSupport;
|
||||
case 32:
|
||||
return hasFramebufferHDR32FSupport;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -51,12 +59,12 @@ public class FixedFunctionShader {
|
|||
public static final String PRECISION_INT = "lowp";
|
||||
public static final String PRECISION_FLOAT = "highp";
|
||||
public static final String PRECISION_SAMPLER = "mediump";
|
||||
|
||||
|
||||
public static final String MACRO_ATTRIB_TEXTURE = "COMPILE_TEXTURE_ATTRIB";
|
||||
public static final String MACRO_ATTRIB_COLOR = "COMPILE_COLOR_ATTRIB";
|
||||
public static final String MACRO_ATTRIB_NORMAL = "COMPILE_NORMAL_ATTRIB";
|
||||
public static final String MACRO_ATTRIB_LIGHTMAP = "COMPILE_LIGHTMAP_ATTRIB";
|
||||
|
||||
|
||||
public static final String MACRO_ENABLE_TEXTURE2D = "COMPILE_ENABLE_TEXTURE2D";
|
||||
public static final String MACRO_ENABLE_LIGHTMAP = "COMPILE_ENABLE_LIGHTMAP";
|
||||
public static final String MACRO_ENABLE_ALPHA_TEST = "COMPILE_ENABLE_ALPHA_TEST";
|
||||
|
@ -98,7 +106,7 @@ public class FixedFunctionShader {
|
|||
|
||||
public static final String UNIFORM_TEXTURE_UNIT_01_NAME = "u_samplerTexture";
|
||||
public static final String UNIFORM_TEXTURE_UNIT_02_NAME = "u_samplerLightmap";
|
||||
|
||||
|
||||
public static final String OUTPUT_COLOR = "output4f";
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.opengl;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -15,36 +15,44 @@ import net.minecraft.client.renderer.GLAllocation;
|
|||
import net.minecraft.util.MathHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class WorldRenderer {
|
||||
|
||||
|
||||
private boolean needsUpdate;
|
||||
private int drawMode;
|
||||
private double xOffset;
|
||||
private double yOffset;
|
||||
private double zOffset;
|
||||
private boolean isDrawing;
|
||||
|
||||
|
||||
private VertexFormat vertexFormat;
|
||||
|
||||
|
||||
private int vertexCount;
|
||||
private ByteBuffer byteBuffer;
|
||||
private IntBuffer intBuffer;
|
||||
private FloatBuffer floatBuffer;
|
||||
|
||||
|
||||
private boolean hasBeenFreed = false;
|
||||
|
||||
public WorldRenderer(int bufferSizeIn) {
|
||||
|
@ -52,14 +60,14 @@ public class WorldRenderer {
|
|||
this.intBuffer = this.byteBuffer.asIntBuffer();
|
||||
this.floatBuffer = this.byteBuffer.asFloatBuffer();
|
||||
}
|
||||
|
||||
|
||||
public void free() {
|
||||
if(!hasBeenFreed) {
|
||||
if (!hasBeenFreed) {
|
||||
hasBeenFreed = true;
|
||||
EagRuntime.freeByteBuffer(byteBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void finalize() {
|
||||
free();
|
||||
}
|
||||
|
@ -69,7 +77,7 @@ public class WorldRenderer {
|
|||
int i = this.byteBuffer.capacity() >> 2;
|
||||
if (parInt1 > (i - pos)) {
|
||||
int k = (((pos + parInt1 + (parInt1 >> 1)) >> 16) + 1) << 16;
|
||||
LogManager.getLogger() .warn("Needed to grow BufferBuilder buffer: Old size " + (i << 2) +
|
||||
LogManager.getLogger().warn("Needed to grow BufferBuilder buffer: Old size " + (i << 2) +
|
||||
" bytes, new size " + (k << 2) + " bytes.");
|
||||
ByteBuffer bytebuffer = GLAllocation.createDirectByteBuffer(k << 2);
|
||||
this.byteBuffer.position(0);
|
||||
|
@ -274,7 +282,7 @@ public class WorldRenderer {
|
|||
}
|
||||
this.intBuffer.put(i, j);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sets color multiplier of a vertex parInt1 indicies before the current vertex
|
||||
*/
|
||||
|
@ -339,8 +347,9 @@ public class WorldRenderer {
|
|||
*/
|
||||
public void addVertexData(int[] vertexData) {
|
||||
this.grow(vertexData.length);
|
||||
PlatformBufferFunctions.put(this.intBuffer, (this.vertexCount * this.vertexFormat.attribStride) >> 2, vertexData);
|
||||
this.vertexCount += vertexData.length / (this.vertexFormat.attribStride >> 2);
|
||||
PlatformBufferFunctions.put(this.intBuffer, (this.vertexCount * this.vertexFormat.attribStride) >> 2,
|
||||
vertexData);
|
||||
this.vertexCount += vertexData.length / (this.vertexFormat.attribStride >> 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -383,7 +392,7 @@ public class WorldRenderer {
|
|||
int i = (byte) ((int) (x * 127.0F)) & 255;
|
||||
int j = (byte) ((int) (y * 127.0F)) & 255;
|
||||
int k = (byte) ((int) (z * 127.0F)) & 255;
|
||||
int l = i | j << 8 | k << 16 | ((byte)id) << 24;
|
||||
int l = i | j << 8 | k << 16 | ((byte) id) << 24;
|
||||
VertexFormat fmt = this.vertexFormat;
|
||||
int i1 = fmt.attribStride;
|
||||
int j1 = (this.vertexCount - 4) * i1 + fmt.attribNormalOffset;
|
||||
|
@ -396,7 +405,7 @@ public class WorldRenderer {
|
|||
/**
|
||||
* set normal of current vertex
|
||||
*/
|
||||
public WorldRenderer normal(float parFloat1, float parFloat2, float parFloat3) { //TODO: crash with particles
|
||||
public WorldRenderer normal(float parFloat1, float parFloat2, float parFloat3) { // TODO: crash with particles
|
||||
VertexFormat fmt = this.vertexFormat;
|
||||
int i = this.vertexCount * fmt.attribStride + fmt.attribNormalOffset;
|
||||
this.byteBuffer.put(i, (byte) ((int) parFloat1 * 127 & 255));
|
||||
|
@ -442,11 +451,11 @@ public class WorldRenderer {
|
|||
int jj1 = (this.vertexCount - 4) * i1 + fmt.attribNormalOffset;
|
||||
this.byteBuffer.putInt(jj1, l);
|
||||
this.byteBuffer.putInt(jj1 + i1, l);
|
||||
if(!b) {
|
||||
if (!b) {
|
||||
this.byteBuffer.putInt(jj1 + i1 * 2, l);
|
||||
}
|
||||
this.byteBuffer.putInt(jj1 + i1 * 3, l);
|
||||
if(b) {
|
||||
if (b) {
|
||||
j1 = (this.vertexCount - 2) * i1;
|
||||
tmpVec1.x = this.byteBuffer.getFloat(j1);
|
||||
tmpVec1.y = this.byteBuffer.getFloat(j1 + 4);
|
||||
|
|
|
@ -13,16 +13,24 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
|||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -119,7 +127,8 @@ public class DeferredStateManager {
|
|||
}
|
||||
|
||||
public static final boolean isRenderingRealisticWater() {
|
||||
return EaglerDeferredPipeline.instance != null && EaglerDeferredPipeline.instance.config.is_rendering_realisticWater;
|
||||
return EaglerDeferredPipeline.instance != null
|
||||
&& EaglerDeferredPipeline.instance.config.is_rendering_realisticWater;
|
||||
}
|
||||
|
||||
public static final boolean isRenderingGlassHighlights() {
|
||||
|
@ -143,9 +152,9 @@ public class DeferredStateManager {
|
|||
|
||||
public static final void reportForwardRenderObjectPosition(int centerX, int centerY, int centerZ) {
|
||||
EaglerDeferredPipeline instance = EaglerDeferredPipeline.instance;
|
||||
if(instance != null && enableForwardRender) {
|
||||
if (instance != null && enableForwardRender) {
|
||||
EaglerDeferredConfig cfg = instance.config;
|
||||
if(!cfg.is_rendering_dynamicLights || !cfg.shaderPackInfo.DYNAMIC_LIGHTS) {
|
||||
if (!cfg.is_rendering_dynamicLights || !cfg.shaderPackInfo.DYNAMIC_LIGHTS) {
|
||||
return;
|
||||
}
|
||||
instance.loadLightSourceBucket(centerX, centerY, centerZ);
|
||||
|
@ -153,10 +162,13 @@ public class DeferredStateManager {
|
|||
}
|
||||
|
||||
public static final void reportForwardRenderObjectPosition2(float x, float y, float z) {
|
||||
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
|
||||
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
|
||||
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
|
||||
reportForwardRenderObjectPosition((int)posX, (int)posY, (int)posZ);
|
||||
float posX = (float) ((x + TileEntityRendererDispatcher.staticPlayerX)
|
||||
- (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
|
||||
float posY = (float) ((y + TileEntityRendererDispatcher.staticPlayerY)
|
||||
- (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
|
||||
float posZ = (float) ((z + TileEntityRendererDispatcher.staticPlayerZ)
|
||||
- (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
|
||||
reportForwardRenderObjectPosition((int) posX, (int) posY, (int) posZ);
|
||||
}
|
||||
|
||||
public static final void setHDRTranslucentPassBlendFunc() {
|
||||
|
@ -350,22 +362,22 @@ public class DeferredStateManager {
|
|||
|
||||
public static void setCurrentSunAngle(Vector3f vec) {
|
||||
currentSunAngle.set(vec);
|
||||
if(vec.y > 0.05f) {
|
||||
if (vec.y > 0.05f) {
|
||||
currentSunLightAngle.x = -vec.x;
|
||||
currentSunLightAngle.y = -vec.y;
|
||||
currentSunLightAngle.z = -vec.z;
|
||||
}else {
|
||||
} else {
|
||||
currentSunLightAngle.set(vec);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setCurrentSunAngle(Vector4f vec) {
|
||||
currentSunAngle.set(vec);
|
||||
if(vec.y > 0.05f) {
|
||||
if (vec.y > 0.05f) {
|
||||
currentSunLightAngle.x = -vec.x;
|
||||
currentSunLightAngle.y = -vec.y;
|
||||
currentSunLightAngle.z = -vec.z;
|
||||
}else {
|
||||
} else {
|
||||
currentSunLightAngle.set(vec);
|
||||
}
|
||||
}
|
||||
|
@ -481,16 +493,16 @@ public class DeferredStateManager {
|
|||
}
|
||||
|
||||
public static void checkGLError(String section) {
|
||||
if(!doCheckErrors) {
|
||||
if (!doCheckErrors) {
|
||||
return;
|
||||
}
|
||||
int i = EaglercraftGPU.glGetError();
|
||||
if(i != 0) {
|
||||
if (i != 0) {
|
||||
EaglerDeferredPipeline.logger.error("########## GL ERROR ##########");
|
||||
EaglerDeferredPipeline.logger.error("@ {}", section);
|
||||
do {
|
||||
EaglerDeferredPipeline.logger.error("#{} - {}", i, EaglercraftGPU.gluErrorString(i));
|
||||
}while((i = EaglercraftGPU.glGetError()) != 0);
|
||||
} while ((i = EaglercraftGPU.glGetError()) != 0);
|
||||
EaglerDeferredPipeline.logger.error("##############################");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,24 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -36,20 +44,20 @@ public class CustomSkin {
|
|||
this.textureInstance = new EaglerSkinTexture(texture, model.width, model.height);
|
||||
this.resourceLocation = null;
|
||||
}
|
||||
|
||||
|
||||
public void load() {
|
||||
if(resourceLocation == null) {
|
||||
if (resourceLocation == null) {
|
||||
resourceLocation = new ResourceLocation("eagler:skins/custom/tex_" + texId++);
|
||||
Minecraft.getMinecraft().getTextureManager().loadTexture(resourceLocation, textureInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ResourceLocation getResource() {
|
||||
return resourceLocation;
|
||||
}
|
||||
|
||||
|
||||
public void delete() {
|
||||
if(resourceLocation != null) {
|
||||
if (resourceLocation != null) {
|
||||
Minecraft.getMinecraft().getTextureManager().deleteTexture(resourceLocation);
|
||||
resourceLocation = null;
|
||||
}
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8.profile;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -35,7 +43,8 @@ public enum DefaultSkins {
|
|||
PRISONER_ALEX(13, "Prisoner Alex", new ResourceLocation("eagler:skins/14.prisoner_alex.png"), SkinModel.ALEX),
|
||||
SCOTTISH_STEVE(14, "Scottish Steve", new ResourceLocation("eagler:skins/15.scottish_steve.png"), SkinModel.STEVE),
|
||||
SCOTTISH_ALEX(15, "Scottish Alex", new ResourceLocation("eagler:skins/16.scottish_alex.png"), SkinModel.ALEX),
|
||||
DEVELOPER_STEVE(16, "Developer Steve", new ResourceLocation("eagler:skins/17.developer_steve.png"), SkinModel.STEVE),
|
||||
DEVELOPER_STEVE(16, "Developer Steve", new ResourceLocation("eagler:skins/17.developer_steve.png"),
|
||||
SkinModel.STEVE),
|
||||
DEVELOPER_ALEX(17, "Developer Alex", new ResourceLocation("eagler:skins/18.developer_alex.png"), SkinModel.ALEX),
|
||||
HEROBRINE(18, "Herobrine", new ResourceLocation("eagler:skins/19.herobrine.png"), SkinModel.ZOMBIE),
|
||||
NOTCH(19, "Notch", new ResourceLocation("eagler:skins/20.notch.png"), SkinModel.STEVE),
|
||||
|
@ -43,43 +52,51 @@ public enum DefaultSkins {
|
|||
ZOMBIE(21, "Zombie", new ResourceLocation("eagler:skins/22.zombie.png"), SkinModel.ZOMBIE),
|
||||
PIG(22, "Pig", new ResourceLocation("eagler:skins/23.pig.png"), SkinModel.STEVE),
|
||||
MOOSHROOM(23, "Mooshroom", new ResourceLocation("eagler:skins/24.mooshroom.png"), SkinModel.STEVE);
|
||||
// LONG_ARMS(24, "Long Arms", new ResourceLocation("eagler:mesh/longarms.fallback.png"), SkinModel.LONG_ARMS),
|
||||
// WEIRD_CLIMBER_DUDE(25, "Weird Climber Dude", new ResourceLocation("eagler:mesh/weirdclimber.fallback.png"), SkinModel.WEIRD_CLIMBER_DUDE),
|
||||
// LAXATIVE_DUDE(26, "Laxative Dude", new ResourceLocation("eagler:mesh/laxativedude.fallback.png"), SkinModel.LAXATIVE_DUDE),
|
||||
// BABY_CHARLES(27, "Baby Charles", new ResourceLocation("eagler:mesh/charles.fallback.png"), SkinModel.BABY_CHARLES),
|
||||
// BABY_WINSTON(28, "Baby Winston", new ResourceLocation("eagler:mesh/winston.fallback.png"), SkinModel.BABY_WINSTON);
|
||||
|
||||
|
||||
// LONG_ARMS(24, "Long Arms", new
|
||||
// ResourceLocation("eagler:mesh/longarms.fallback.png"), SkinModel.LONG_ARMS),
|
||||
// WEIRD_CLIMBER_DUDE(25, "Weird Climber Dude", new
|
||||
// ResourceLocation("eagler:mesh/weirdclimber.fallback.png"),
|
||||
// SkinModel.WEIRD_CLIMBER_DUDE),
|
||||
// LAXATIVE_DUDE(26, "Laxative Dude", new
|
||||
// ResourceLocation("eagler:mesh/laxativedude.fallback.png"),
|
||||
// SkinModel.LAXATIVE_DUDE),
|
||||
// BABY_CHARLES(27, "Baby Charles", new
|
||||
// ResourceLocation("eagler:mesh/charles.fallback.png"),
|
||||
// SkinModel.BABY_CHARLES),
|
||||
// BABY_WINSTON(28, "Baby Winston", new
|
||||
// ResourceLocation("eagler:mesh/winston.fallback.png"),
|
||||
// SkinModel.BABY_WINSTON);
|
||||
|
||||
// public static final DefaultSkins[] defaultSkinsMap = new DefaultSkins[29];
|
||||
public static final DefaultSkins[] defaultSkinsMap = new DefaultSkins[24];
|
||||
|
||||
|
||||
public final int id;
|
||||
public final String name;
|
||||
public final ResourceLocation location;
|
||||
public final SkinModel model;
|
||||
|
||||
|
||||
private DefaultSkins(int id, String name, ResourceLocation location, SkinModel model) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.location = location;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
|
||||
public static DefaultSkins getSkinFromId(int id) {
|
||||
DefaultSkins e = null;
|
||||
if(id >= 0 && id < defaultSkinsMap.length) {
|
||||
if (id >= 0 && id < defaultSkinsMap.length) {
|
||||
e = defaultSkinsMap[id];
|
||||
}
|
||||
if(e != null) {
|
||||
if (e != null) {
|
||||
return e;
|
||||
}else {
|
||||
} else {
|
||||
return DEFAULT_STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
DefaultSkins[] skins = values();
|
||||
for(int i = 0; i < skins.length; ++i) {
|
||||
for (int i = 0; i < skins.length; ++i) {
|
||||
defaultSkinsMap[skins[i].id] = skins[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,24 @@ import net.minecraft.nbt.NBTTagList;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -35,51 +43,51 @@ import net.minecraft.util.ResourceLocation;
|
|||
public class EaglerProfile {
|
||||
|
||||
private static String username;
|
||||
|
||||
|
||||
public static int presetSkinId;
|
||||
public static int customSkinId;
|
||||
|
||||
public static int presetCapeId;
|
||||
public static int customCapeId;
|
||||
|
||||
|
||||
public static final List<CustomSkin> customSkins = new ArrayList();
|
||||
|
||||
public static final List<CustomCape> customCapes = new ArrayList();
|
||||
|
||||
|
||||
public static final EaglercraftRandom rand;
|
||||
|
||||
|
||||
public static ResourceLocation getActiveSkinResourceLocation() {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
if (presetSkinId == -1) {
|
||||
if (customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return customSkins.get(customSkinId).getResource();
|
||||
}else {
|
||||
} else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].location;
|
||||
}
|
||||
}else {
|
||||
if(presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
} else {
|
||||
if (presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return DefaultSkins.defaultSkinsMap[presetSkinId].location;
|
||||
}else {
|
||||
} else {
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static SkinModel getActiveSkinModel() {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
if (presetSkinId == -1) {
|
||||
if (customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return customSkins.get(customSkinId).model;
|
||||
}else {
|
||||
} else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].model;
|
||||
}
|
||||
}else {
|
||||
if(presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
} else {
|
||||
if (presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return DefaultSkins.defaultSkinsMap[presetSkinId].model;
|
||||
}else {
|
||||
} else {
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].model;
|
||||
}
|
||||
|
@ -87,18 +95,18 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
public static ResourceLocation getActiveCapeResourceLocation() {
|
||||
if(presetCapeId == -1) {
|
||||
if(customCapeId >= 0 && customCapeId < customCapes.size()) {
|
||||
if (presetCapeId == -1) {
|
||||
if (customCapeId >= 0 && customCapeId < customCapes.size()) {
|
||||
return customCapes.get(customCapeId).getResource();
|
||||
}else {
|
||||
} else {
|
||||
customCapeId = -1;
|
||||
presetCapeId = 0;
|
||||
return DefaultCapes.defaultCapesMap[0].location;
|
||||
}
|
||||
}else {
|
||||
if(presetCapeId >= 0 && presetCapeId < DefaultCapes.defaultCapesMap.length) {
|
||||
} else {
|
||||
if (presetCapeId >= 0 && presetCapeId < DefaultCapes.defaultCapesMap.length) {
|
||||
return DefaultCapes.defaultCapesMap[presetCapeId].location;
|
||||
}else {
|
||||
} else {
|
||||
presetCapeId = 0;
|
||||
return DefaultCapes.defaultCapesMap[0].location;
|
||||
}
|
||||
|
@ -116,24 +124,24 @@ public class EaglerProfile {
|
|||
public static void setName(String str) {
|
||||
username = str;
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if(mc != null) {
|
||||
if (mc != null) {
|
||||
mc.getSession().reset();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getSkinPacket() {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
if (presetSkinId == -1) {
|
||||
if (customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return SkinPackets.writeMySkinCustom(customSkins.get(customSkinId));
|
||||
}else {
|
||||
} else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
return SkinPackets.writeMySkinPreset(0);
|
||||
}
|
||||
}else {
|
||||
if(presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
} else {
|
||||
if (presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return SkinPackets.writeMySkinPreset(presetSkinId);
|
||||
}else {
|
||||
} else {
|
||||
presetSkinId = 0;
|
||||
return SkinPackets.writeMySkinPreset(0);
|
||||
}
|
||||
|
@ -141,18 +149,18 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
public static byte[] getCapePacket() {
|
||||
if(presetCapeId == -1) {
|
||||
if(customCapeId >= 0 && customCapeId < customCapes.size()) {
|
||||
if (presetCapeId == -1) {
|
||||
if (customCapeId >= 0 && customCapeId < customCapes.size()) {
|
||||
return CapePackets.writeMyCapeCustom(customCapes.get(customCapeId));
|
||||
}else {
|
||||
} else {
|
||||
customCapeId = -1;
|
||||
presetCapeId = 0;
|
||||
return CapePackets.writeMyCapePreset(0);
|
||||
}
|
||||
}else {
|
||||
if(presetCapeId >= 0 && presetCapeId < DefaultCapes.defaultCapesMap.length) {
|
||||
} else {
|
||||
if (presetCapeId >= 0 && presetCapeId < DefaultCapes.defaultCapesMap.length) {
|
||||
return CapePackets.writeMyCapePreset(presetCapeId);
|
||||
}else {
|
||||
} else {
|
||||
presetCapeId = 0;
|
||||
return CapePackets.writeMyCapePreset(0);
|
||||
}
|
||||
|
@ -160,8 +168,8 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
private static boolean doesSkinExist(String name) {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
if(customSkins.get(i).name.equalsIgnoreCase(name)) {
|
||||
for (int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
if (customSkins.get(i).name.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -169,8 +177,8 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
private static boolean doesCapeExist(String name) {
|
||||
for(int i = 0, l = customCapes.size(); i < l; ++i) {
|
||||
if(customCapes.get(i).name.equalsIgnoreCase(name)) {
|
||||
for (int i = 0, l = customCapes.size(); i < l; ++i) {
|
||||
if (customCapes.get(i).name.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -178,10 +186,10 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
public static int addCustomSkin(String fileName, byte[] rawSkin) {
|
||||
if(doesSkinExist(fileName)) {
|
||||
if (doesSkinExist(fileName)) {
|
||||
String newName;
|
||||
int i = 2;
|
||||
while(doesSkinExist(newName = fileName + " (" + i + ")")) {
|
||||
while (doesSkinExist(newName = fileName + " (" + i + ")")) {
|
||||
++i;
|
||||
}
|
||||
fileName = newName;
|
||||
|
@ -194,10 +202,10 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
public static int addCustomCape(String fileName, byte[] rawCape23x17RGB) {
|
||||
if(doesCapeExist(fileName)) {
|
||||
if (doesCapeExist(fileName)) {
|
||||
String newName;
|
||||
int i = 2;
|
||||
while(doesCapeExist(newName = fileName + " (" + i + ")")) {
|
||||
while (doesCapeExist(newName = fileName + " (" + i + ")")) {
|
||||
++i;
|
||||
}
|
||||
fileName = newName;
|
||||
|
@ -210,14 +218,14 @@ public class EaglerProfile {
|
|||
}
|
||||
|
||||
public static void clearCustomSkins() {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
for (int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
customSkins.get(i).delete();
|
||||
}
|
||||
customSkins.clear();
|
||||
}
|
||||
|
||||
public static void clearCustomCapes() {
|
||||
for(int i = 0, l = customCapes.size(); i < l; ++i) {
|
||||
for (int i = 0, l = customCapes.size(); i < l; ++i) {
|
||||
customCapes.get(i).delete();
|
||||
}
|
||||
customCapes.clear();
|
||||
|
@ -227,10 +235,12 @@ public class EaglerProfile {
|
|||
read(EagRuntime.getStorage("p"));
|
||||
}
|
||||
|
||||
@JSBody(params = { "name", "data" }, script = "document.cookie = name + '=' + encodeURIComponent(data) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';")
|
||||
@JSBody(params = { "name",
|
||||
"data" }, script = "document.cookie = name + '=' + encodeURIComponent(data) + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';")
|
||||
public static native void setCookie(String name, String data);
|
||||
|
||||
@JSBody(params = { "name" }, script = "var value = '; ' + document.cookie; var parts = value.split('; ' + name + '='); if (parts.length == 2) return decodeURIComponent(parts.pop().split(';').shift()); return '';")
|
||||
@JSBody(params = {
|
||||
"name" }, script = "var value = '; ' + document.cookie; var parts = value.split('; ' + name + '='); if (parts.length == 2) return decodeURIComponent(parts.pop().split(';').shift()); return '';")
|
||||
public static native String getCookie(String name);
|
||||
|
||||
@JSBody(params = { "name", "data" }, script = "localStorage.setItem(name, data);")
|
||||
|
@ -246,7 +256,7 @@ public class EaglerProfile {
|
|||
|
||||
public static void updateUsernameCookieFromLocalStorage() {
|
||||
String name = getLocalStorage("username");
|
||||
if(name != null && !name.isEmpty()) {
|
||||
if (name != null && !name.isEmpty()) {
|
||||
username = name;
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +269,7 @@ public class EaglerProfile {
|
|||
NBTTagCompound profile;
|
||||
try {
|
||||
profile = CompressedStreamTools.readCompressed(new EaglerInputStream(profileStorage));
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -270,12 +280,14 @@ public class EaglerProfile {
|
|||
presetSkinId = profile.getInteger("presetSkin");
|
||||
customSkinId = profile.getInteger("customSkin");
|
||||
|
||||
if(profile.hasKey("presetCape", 99)) presetCapeId = profile.getInteger("presetCape");
|
||||
if(profile.hasKey("customCape", 99)) customCapeId = profile.getInteger("customCape");
|
||||
if (profile.hasKey("presetCape", 99))
|
||||
presetCapeId = profile.getInteger("presetCape");
|
||||
if (profile.hasKey("customCape", 99))
|
||||
customCapeId = profile.getInteger("customCape");
|
||||
|
||||
String loadUsername = profile.getString("username").trim();
|
||||
|
||||
if(!loadUsername.isEmpty()) {
|
||||
if (!loadUsername.isEmpty()) {
|
||||
username = loadUsername.replaceAll("[^A-Za-z0-9]", "_");
|
||||
updateUsernameCookies();
|
||||
}
|
||||
|
@ -283,14 +295,15 @@ public class EaglerProfile {
|
|||
clearCustomSkins();
|
||||
|
||||
NBTTagList skinsList = profile.getTagList("skins", 10);
|
||||
for(int i = 0, l = skinsList.tagCount(); i < l; ++i) {
|
||||
for (int i = 0, l = skinsList.tagCount(); i < l; ++i) {
|
||||
NBTTagCompound skin = skinsList.getCompoundTagAt(i);
|
||||
String skinName = skin.getString("name");
|
||||
byte[] skinData = skin.getByteArray("data");
|
||||
if(skinData.length != 16384) continue;
|
||||
for(int y = 20; y < 32; ++y) {
|
||||
for(int x = 16; x < 40; ++x) {
|
||||
skinData[(y << 8) | (x << 2)] = (byte)0xff;
|
||||
if (skinData.length != 16384)
|
||||
continue;
|
||||
for (int y = 20; y < 32; ++y) {
|
||||
for (int x = 16; x < 40; ++x) {
|
||||
skinData[(y << 8) | (x << 2)] = (byte) 0xff;
|
||||
}
|
||||
}
|
||||
int skinModel = skin.getByte("model");
|
||||
|
@ -299,28 +312,29 @@ public class EaglerProfile {
|
|||
customSkins.add(newSkin);
|
||||
}
|
||||
|
||||
if(profile.hasKey("capes", 9)) {
|
||||
if (profile.hasKey("capes", 9)) {
|
||||
clearCustomCapes();
|
||||
NBTTagList capesList = profile.getTagList("capes", 10);
|
||||
for(int i = 0, l = capesList.tagCount(); i < l; ++i) {
|
||||
for (int i = 0, l = capesList.tagCount(); i < l; ++i) {
|
||||
NBTTagCompound cape = capesList.getCompoundTagAt(i);
|
||||
String capeName = cape.getString("name");
|
||||
byte[] capeData = cape.getByteArray("data");
|
||||
if(capeData.length != 1173) continue;
|
||||
if (capeData.length != 1173)
|
||||
continue;
|
||||
CustomCape newCape = new CustomCape(capeName, capeData);
|
||||
newCape.load();
|
||||
customCapes.add(newCape);
|
||||
}
|
||||
}
|
||||
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId < 0 || customSkinId >= customSkins.size()) {
|
||||
|
||||
if (presetSkinId == -1) {
|
||||
if (customSkinId < 0 || customSkinId >= customSkins.size()) {
|
||||
presetSkinId = 0;
|
||||
customSkinId = -1;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
customSkinId = -1;
|
||||
if(presetSkinId < 0 || presetSkinId >= DefaultSkins.defaultSkinsMap.length) {
|
||||
if (presetSkinId < 0 || presetSkinId >= DefaultSkins.defaultSkinsMap.length) {
|
||||
presetSkinId = 0;
|
||||
}
|
||||
}
|
||||
|
@ -335,17 +349,17 @@ public class EaglerProfile {
|
|||
profile.setInteger("customCape", customCapeId);
|
||||
profile.setString("username", username);
|
||||
NBTTagList skinsList = new NBTTagList();
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
for (int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
CustomSkin sk = customSkins.get(i);
|
||||
NBTTagCompound skin = new NBTTagCompound();
|
||||
skin.setString("name", sk.name);
|
||||
skin.setByteArray("data", sk.texture);
|
||||
skin.setByte("model", (byte)sk.model.id);
|
||||
skin.setByte("model", (byte) sk.model.id);
|
||||
skinsList.appendTag(skin);
|
||||
}
|
||||
profile.setTag("skins", skinsList);
|
||||
NBTTagList capesList = new NBTTagList();
|
||||
for(int i = 0, l = customCapes.size(); i < l; ++i) {
|
||||
for (int i = 0, l = customCapes.size(); i < l; ++i) {
|
||||
CustomCape cp = customCapes.get(i);
|
||||
NBTTagCompound cape = new NBTTagCompound();
|
||||
cape.setString("name", cp.name);
|
||||
|
@ -364,7 +378,7 @@ public class EaglerProfile {
|
|||
|
||||
public static void save() {
|
||||
byte[] b = write();
|
||||
if(b != null) {
|
||||
if (b != null) {
|
||||
EagRuntime.setStorage("p", b);
|
||||
}
|
||||
}
|
||||
|
@ -374,18 +388,19 @@ public class EaglerProfile {
|
|||
"Yeeish", "Yeeish", "Yee", "Yee", "Yeer", "Yeeler", "Eagler", "Eagl",
|
||||
"Darver", "Darvler", "Vool", "Vigg", "Vigg", "Deev", "Yigg", "Yeeg"
|
||||
};
|
||||
|
||||
|
||||
rand = new EaglercraftRandom();
|
||||
|
||||
|
||||
do {
|
||||
username = defaultNames[rand.nextInt(defaultNames.length)] + defaultNames[rand.nextInt(defaultNames.length)] + (100 + rand.nextInt(900));
|
||||
}while(username.length() > 16);
|
||||
|
||||
username = defaultNames[rand.nextInt(defaultNames.length)] + defaultNames[rand.nextInt(defaultNames.length)]
|
||||
+ (100 + rand.nextInt(900));
|
||||
} while (username.length() > 16);
|
||||
|
||||
setName(username);
|
||||
|
||||
|
||||
do {
|
||||
presetSkinId = rand.nextInt(DefaultSkins.defaultSkinsMap.length);
|
||||
}while(DefaultSkins.defaultSkinsMap[presetSkinId].model.highPoly != null);
|
||||
} while (DefaultSkins.defaultSkinsMap[presetSkinId].model.highPoly != null);
|
||||
customSkinId = -1;
|
||||
|
||||
presetCapeId = 0;
|
||||
|
|
|
@ -9,16 +9,24 @@ import net.minecraft.client.renderer.texture.TextureUtil;
|
|||
import net.minecraft.client.resources.IResourceManager;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -32,8 +40,9 @@ public class EaglerSkinTexture implements ITextureObject {
|
|||
private int textureId = -1;
|
||||
|
||||
public EaglerSkinTexture(int[] pixels, int width, int height) {
|
||||
if(pixels.length != width * height) {
|
||||
throw new IllegalArgumentException("Wrong data length " + pixels.length * 4 + " for " + width + "x" + height + " texture");
|
||||
if (pixels.length != width * height) {
|
||||
throw new IllegalArgumentException(
|
||||
"Wrong data length " + pixels.length * 4 + " for " + width + "x" + height + " texture");
|
||||
}
|
||||
this.pixels = pixels;
|
||||
this.width = width;
|
||||
|
@ -41,11 +50,12 @@ public class EaglerSkinTexture implements ITextureObject {
|
|||
}
|
||||
|
||||
public EaglerSkinTexture(byte[] pixels, int width, int height) {
|
||||
if(pixels.length != width * height * 4) {
|
||||
throw new IllegalArgumentException("Wrong data length " + pixels.length + " for " + width + "x" + height + " texture");
|
||||
if (pixels.length != width * height * 4) {
|
||||
throw new IllegalArgumentException(
|
||||
"Wrong data length " + pixels.length + " for " + width + "x" + height + " texture");
|
||||
}
|
||||
int[] p = new int[pixels.length >> 2];
|
||||
for(int i = 0, j; i < p.length; ++i) {
|
||||
for (int i = 0, j; i < p.length; ++i) {
|
||||
j = i << 2;
|
||||
p[i] = (((int) pixels[j] & 0xFF) << 24) | (((int) pixels[j + 1] & 0xFF) << 16)
|
||||
| (((int) pixels[j + 2] & 0xFF) << 8) | ((int) pixels[j + 3] & 0xFF);
|
||||
|
@ -56,18 +66,19 @@ public class EaglerSkinTexture implements ITextureObject {
|
|||
}
|
||||
|
||||
public void copyPixelsIn(int[] pixels) {
|
||||
if(this.pixels.length != pixels.length) {
|
||||
throw new IllegalArgumentException("Tried to copy " + pixels.length + " pixels into a " + this.pixels.length + " pixel texture");
|
||||
if (this.pixels.length != pixels.length) {
|
||||
throw new IllegalArgumentException(
|
||||
"Tried to copy " + pixels.length + " pixels into a " + this.pixels.length + " pixel texture");
|
||||
}
|
||||
System.arraycopy(pixels, 0, this.pixels, 0, pixels.length);
|
||||
if(textureId != -1) {
|
||||
if (textureId != -1) {
|
||||
TextureUtil.uploadTextureImageAllocate(textureId, new ImageData(width, height, pixels, true), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTexture(IResourceManager var1) throws IOException {
|
||||
if(textureId == -1) {
|
||||
if (textureId == -1) {
|
||||
textureId = GlStateManager.generateTexture();
|
||||
TextureUtil.uploadTextureImageAllocate(textureId, new ImageData(width, height, pixels, true), false, false);
|
||||
}
|
||||
|
@ -87,7 +98,7 @@ public class EaglerSkinTexture implements ITextureObject {
|
|||
public void restoreLastBlurMipmap() {
|
||||
// no
|
||||
}
|
||||
|
||||
|
||||
public void free() {
|
||||
GlStateManager.deleteTexture(textureId);
|
||||
textureId = -1;
|
||||
|
|
|
@ -11,16 +11,24 @@ import net.minecraft.client.multiplayer.GuiConnecting;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -40,19 +48,19 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
|||
this.retAfterAuthScreen = retAfterAuthScreen;
|
||||
this.parent = parent;
|
||||
String authRequired = HandshakePacketTypes.AUTHENTICATION_REQUIRED;
|
||||
if(message.startsWith(authRequired)) {
|
||||
if (message.startsWith(authRequired)) {
|
||||
message = message.substring(authRequired.length()).trim();
|
||||
}
|
||||
if(message.length() > 0 && message.charAt(0) == '[') {
|
||||
if (message.length() > 0 && message.charAt(0) == '[') {
|
||||
int idx = message.indexOf(']', 1);
|
||||
if(idx != -1) {
|
||||
if (idx != -1) {
|
||||
String authType = message.substring(1, idx);
|
||||
int type = Integer.MAX_VALUE;
|
||||
try {
|
||||
type = Integer.parseInt(authType);
|
||||
}catch(NumberFormatException ex) {
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
if(type != Integer.MAX_VALUE) {
|
||||
if (type != Integer.MAX_VALUE) {
|
||||
authTypeForWarning = type;
|
||||
message = message.substring(idx + 1).trim();
|
||||
}
|
||||
|
@ -62,10 +70,10 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
|||
}
|
||||
|
||||
public void initGui() {
|
||||
if(authTypeForWarning != Integer.MAX_VALUE) {
|
||||
if (authTypeForWarning != Integer.MAX_VALUE) {
|
||||
GuiScreen scr = ConnectionHandshake.displayAuthProtocolConfirm(authTypeForWarning, parent, this);
|
||||
authTypeForWarning = Integer.MAX_VALUE;
|
||||
if(scr != null) {
|
||||
if (scr != null) {
|
||||
mc.displayGuiScreen(scr);
|
||||
allowPlaintext = true;
|
||||
return;
|
||||
|
@ -78,7 +86,8 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
|||
continueButton.enabled = false;
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 80 + 37,
|
||||
I18n.format("gui.cancel", new Object[0])));
|
||||
this.password = new GuiPasswordTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 40, 200, 20); // 116
|
||||
this.password = new GuiPasswordTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 40,
|
||||
200, 20); // 116
|
||||
this.password.setFocused(true);
|
||||
this.password.setCanLoseFocus(false);
|
||||
}
|
||||
|
@ -88,9 +97,9 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
|||
}
|
||||
|
||||
protected void actionPerformed(GuiButton parGuiButton) {
|
||||
if(parGuiButton.id == 1) {
|
||||
if (parGuiButton.id == 1) {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, password.getText()));
|
||||
}else {
|
||||
} else {
|
||||
this.mc.displayGuiScreen(parent);
|
||||
if (!PlatformNetworking.playConnectionState().isClosed()) {
|
||||
PlatformNetworking.playDisconnect();
|
||||
|
@ -109,9 +118,9 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
|||
|
||||
protected void keyTyped(char parChar1, int parInt1) {
|
||||
String pass = password.getText();
|
||||
if(parInt1 == KeyboardConstants.KEY_RETURN && pass.length() > 0) {
|
||||
if (parInt1 == KeyboardConstants.KEY_RETURN && pass.length() > 0) {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, pass, allowPlaintext));
|
||||
}else {
|
||||
} else {
|
||||
this.password.textboxKeyTyped(parChar1, parInt1);
|
||||
this.continueButton.enabled = password.getText().length() > 0;
|
||||
}
|
||||
|
|
|
@ -20,16 +20,24 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -66,20 +74,22 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
usernameField = new GuiTextField(0, fontRendererObj, width / 2 - 20 + 1, height / 6 + 24 + 1, 138, 20);
|
||||
usernameField.setFocused(true);
|
||||
usernameField.setText(EaglerProfile.getName());
|
||||
selectedSlot = EaglerProfile.presetSkinId == -1 ? EaglerProfile.customSkinId : (EaglerProfile.presetSkinId + EaglerProfile.customSkins.size());
|
||||
selectedSlot = EaglerProfile.presetSkinId == -1 ? EaglerProfile.customSkinId
|
||||
: (EaglerProfile.presetSkinId + EaglerProfile.customSkins.size());
|
||||
buttonList.add(new GuiButton(0, width / 2 - 100, height / 6 + 168, I18n.format("gui.done")));
|
||||
buttonList.add(new GuiButton(1, width / 2 - 21, height / 6 + 110, 71, 20, I18n.format("editProfile.addSkin")));
|
||||
buttonList.add(new GuiButton(2, width / 2 - 21 + 71, height / 6 + 110, 72, 20, I18n.format("editProfile.clearSkin")));
|
||||
buttonList.add(
|
||||
new GuiButton(2, width / 2 - 21 + 71, height / 6 + 110, 72, 20, I18n.format("editProfile.clearSkin")));
|
||||
}
|
||||
|
||||
private void updateOptions() {
|
||||
int numCustom = EaglerProfile.customSkins.size();
|
||||
String[] n = new String[numCustom + DefaultSkins.defaultSkinsMap.length];
|
||||
for(int i = 0; i < numCustom; ++i) {
|
||||
for (int i = 0; i < numCustom; ++i) {
|
||||
n[i] = EaglerProfile.customSkins.get(i).name;
|
||||
}
|
||||
int numDefault = DefaultSkins.defaultSkinsMap.length;
|
||||
for(int j = 0; j < numDefault; ++j) {
|
||||
for (int j = 0; j < numDefault; ++j) {
|
||||
n[numCustom + j] = DefaultSkins.defaultSkinsMap[j].name;
|
||||
}
|
||||
dropDownOptions = n;
|
||||
|
@ -90,29 +100,32 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
drawCenteredString(fontRendererObj, screenTitle, width / 2, 15, 16777215);
|
||||
drawString(fontRendererObj, I18n.format("editProfile.username"), width / 2 - 20, height / 6 + 8, 10526880);
|
||||
drawString(fontRendererObj, I18n.format("editProfile.playerSkin"), width / 2 - 20, height / 6 + 66, 10526880);
|
||||
|
||||
|
||||
mousex = mx;
|
||||
mousey = my;
|
||||
|
||||
|
||||
int skinX = width / 2 - 120;
|
||||
int skinY = height / 6 + 8;
|
||||
int skinWidth = 80;
|
||||
int skinHeight = 130;
|
||||
|
||||
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xFFA0A0A0);
|
||||
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xFF000015);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(skinX + 2, skinY - 9, 0.0f);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
int numberOfCustomSkins = EaglerProfile.customSkins.size();
|
||||
int skid = selectedSlot - numberOfCustomSkins;
|
||||
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model : DefaultSkins.getSkinFromId(skid).model;
|
||||
if(selectedSkinModel == SkinModel.STEVE || selectedSkinModel == SkinModel.ALEX || (selectedSkinModel.highPoly != null && !this.mc.gameSettings.enableFNAWSkins)) {
|
||||
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model
|
||||
: DefaultSkins.getSkinFromId(skid).model;
|
||||
if (selectedSkinModel == SkinModel.STEVE || selectedSkinModel == SkinModel.ALEX
|
||||
|| (selectedSkinModel.highPoly != null && !this.mc.gameSettings.enableFNAWSkins)) {
|
||||
String capesText = I18n.format("editProfile.capes");
|
||||
int color = 10526880;
|
||||
if(mx > skinX - 10 && my > skinY - 16 && mx < skinX + (fontRendererObj.getStringWidth(capesText) * 0.75f) + 10 && my < skinY + 7) {
|
||||
if (mx > skinX - 10 && my > skinY - 16
|
||||
&& mx < skinX + (fontRendererObj.getStringWidth(capesText) * 0.75f) + 10 && my < skinY + 7) {
|
||||
color = 0xFFCCCC44;
|
||||
Mouse.showCursor(EnumCursorType.HAND);
|
||||
}
|
||||
|
@ -120,157 +133,163 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
usernameField.drawTextBox();
|
||||
if(dropDownOpen || newSkinWaitSteveOrAlex) {
|
||||
if (dropDownOpen || newSkinWaitSteveOrAlex) {
|
||||
super.drawScreen(0, 0, partialTicks);
|
||||
}else {
|
||||
} else {
|
||||
super.drawScreen(mx, my, partialTicks);
|
||||
}
|
||||
|
||||
if(selectedSkinModel.highPoly != null) {
|
||||
drawCenteredString(fontRendererObj, I18n.format(this.mc.gameSettings.enableFNAWSkins ? "editProfile.disableFNAW" : "editProfile.enableFNAW"), width / 2, height / 6 + 150, 10526880);
|
||||
if (selectedSkinModel.highPoly != null) {
|
||||
drawCenteredString(fontRendererObj, I18n.format(
|
||||
this.mc.gameSettings.enableFNAWSkins ? "editProfile.disableFNAW" : "editProfile.enableFNAW"),
|
||||
width / 2, height / 6 + 150, 10526880);
|
||||
}
|
||||
|
||||
|
||||
skinX = width / 2 - 20;
|
||||
skinY = height / 6 + 82;
|
||||
skinWidth = 140;
|
||||
skinHeight = 22;
|
||||
|
||||
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
|
||||
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 21, skinY + skinHeight - 1, -16777216);
|
||||
drawRect(skinX + skinWidth - 20, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216);
|
||||
|
||||
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
|
||||
mc.getTextureManager().bindTexture(eaglerGui);
|
||||
drawTexturedModalRect(skinX + skinWidth - 18, skinY + 3, 0, 0, 16, 16);
|
||||
|
||||
|
||||
drawString(fontRendererObj, dropDownOptions[selectedSlot], skinX + 5, skinY + 7, 14737632);
|
||||
|
||||
|
||||
skinX = width / 2 - 20;
|
||||
skinY = height / 6 + 103;
|
||||
skinWidth = 140;
|
||||
skinHeight = (height - skinY - 10);
|
||||
slotsVisible = (skinHeight / 10);
|
||||
if(slotsVisible > dropDownOptions.length) slotsVisible = dropDownOptions.length;
|
||||
if (slotsVisible > dropDownOptions.length)
|
||||
slotsVisible = dropDownOptions.length;
|
||||
skinHeight = slotsVisible * 10 + 7;
|
||||
skinsHeight = skinHeight;
|
||||
if(scrollPos == -1) {
|
||||
if (scrollPos == -1) {
|
||||
scrollPos = selectedSlot - 2;
|
||||
}
|
||||
if(scrollPos > (dropDownOptions.length - slotsVisible)) {
|
||||
if (scrollPos > (dropDownOptions.length - slotsVisible)) {
|
||||
scrollPos = (dropDownOptions.length - slotsVisible);
|
||||
}
|
||||
if(scrollPos < 0) {
|
||||
if (scrollPos < 0) {
|
||||
scrollPos = 0;
|
||||
}
|
||||
if(dropDownOpen) {
|
||||
if (dropDownOpen) {
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
|
||||
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216);
|
||||
for(int i = 0; i < slotsVisible; i++) {
|
||||
if(i + scrollPos < dropDownOptions.length) {
|
||||
if(selectedSlot == i + scrollPos) {
|
||||
drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x77ffffff);
|
||||
}else if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i*10 + 5) && my < (skinY + i*10 + 15)) {
|
||||
drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x55ffffff);
|
||||
for (int i = 0; i < slotsVisible; i++) {
|
||||
if (i + scrollPos < dropDownOptions.length) {
|
||||
if (selectedSlot == i + scrollPos) {
|
||||
drawRect(skinX + 1, skinY + i * 10 + 4, skinX + skinWidth - 1, skinY + i * 10 + 14, 0x77ffffff);
|
||||
} else if (mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5)
|
||||
&& my < (skinY + i * 10 + 15)) {
|
||||
drawRect(skinX + 1, skinY + i * 10 + 4, skinX + skinWidth - 1, skinY + i * 10 + 14, 0x55ffffff);
|
||||
}
|
||||
drawString(fontRendererObj, dropDownOptions[i + scrollPos], skinX + 5, skinY + 5 + i*10, 14737632);
|
||||
drawString(fontRendererObj, dropDownOptions[i + scrollPos], skinX + 5, skinY + 5 + i * 10,
|
||||
14737632);
|
||||
}
|
||||
}
|
||||
int scrollerSize = skinHeight * slotsVisible / dropDownOptions.length;
|
||||
int scrollerPos = skinHeight * scrollPos / dropDownOptions.length;
|
||||
drawRect(skinX + skinWidth - 4, skinY + scrollerPos + 1, skinX + skinWidth - 1, skinY + scrollerPos + scrollerSize, 0xff888888);
|
||||
drawRect(skinX + skinWidth - 4, skinY + scrollerPos + 1, skinX + skinWidth - 1,
|
||||
skinY + scrollerPos + scrollerSize, 0xff888888);
|
||||
}
|
||||
|
||||
if(!EagRuntime.getConfiguration().isDemo()) {
|
||||
if (!EagRuntime.getConfiguration().isDemo()) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
String text = I18n.format("editProfile.importExport");
|
||||
|
||||
|
||||
int w = mc.fontRendererObj.getStringWidth(text);
|
||||
boolean hover = mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12;
|
||||
if(hover) {
|
||||
if (hover) {
|
||||
Mouse.showCursor(EnumCursorType.HAND);
|
||||
}
|
||||
|
||||
|
||||
drawString(mc.fontRendererObj, EnumChatFormatting.UNDERLINE + text, 5, 5, hover ? 0xFFEEEE22 : 0xFFCCCCCC);
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
int xx = width / 2 - 80;
|
||||
int yy = height / 6 + 130;
|
||||
|
||||
if(newSkinWaitSteveOrAlex && selectedSlot < numberOfCustomSkins) {
|
||||
|
||||
if (newSkinWaitSteveOrAlex && selectedSlot < numberOfCustomSkins) {
|
||||
skinWidth = 70;
|
||||
skinHeight = 120;
|
||||
|
||||
|
||||
CustomSkin newSkin = EaglerProfile.customSkins.get(selectedSlot);
|
||||
|
||||
|
||||
GlStateManager.clear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
skinX = width / 2 - 90;
|
||||
skinY = height / 4;
|
||||
xx = skinX + 35;
|
||||
yy = skinY + 117;
|
||||
|
||||
|
||||
boolean mouseOver = mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight;
|
||||
int cc = mouseOver ? 0xFFDDDD99 : 0xFF555555;
|
||||
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawRect(0, 0, width, height, 0xbb000000);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xbb000000);
|
||||
GlStateManager.disableBlend();
|
||||
|
||||
|
||||
drawRect(skinX, skinY, skinX + 1, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + 1, cc);
|
||||
drawRect(skinX + skinWidth - 1, skinY, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY + skinHeight - 1, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
|
||||
if(mouseOver) {
|
||||
|
||||
if (mouseOver) {
|
||||
drawCenteredString(fontRendererObj, "Steve", skinX + skinWidth / 2, skinY + skinHeight + 6, cc);
|
||||
}
|
||||
|
||||
|
||||
SkinPreviewRenderer.renderPreview(xx, yy, mx, my, false, SkinModel.STEVE, newSkin.getResource(),
|
||||
EaglerProfile.getActiveCapeResourceLocation());
|
||||
|
||||
|
||||
skinX = width / 2 + 20;
|
||||
skinY = height / 4;
|
||||
xx = skinX + 35;
|
||||
yy = skinY + 117;
|
||||
|
||||
|
||||
mouseOver = mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight;
|
||||
cc = mouseOver ? 0xFFDDDD99 : 0xFF555555;
|
||||
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xbb000000);
|
||||
GlStateManager.disableBlend();
|
||||
|
||||
|
||||
drawRect(skinX, skinY, skinX + 1, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + 1, cc);
|
||||
drawRect(skinX + skinWidth - 1, skinY, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY + skinHeight - 1, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
|
||||
if(mouseOver) {
|
||||
|
||||
if (mouseOver) {
|
||||
drawCenteredString(fontRendererObj, "Alex", skinX + skinWidth / 2, skinY + skinHeight + 8, cc);
|
||||
}
|
||||
|
||||
|
||||
SkinPreviewRenderer.renderPreview(xx, yy, mx, my, false, SkinModel.ALEX, newSkin.getResource(),
|
||||
EaglerProfile.getActiveCapeResourceLocation());
|
||||
}else {
|
||||
} else {
|
||||
skinX = this.width / 2 - 120;
|
||||
skinY = this.height / 6 + 8;
|
||||
skinWidth = 80;
|
||||
skinHeight = 130;
|
||||
|
||||
|
||||
ResourceLocation texture;
|
||||
if(skid < 0) {
|
||||
if (skid < 0) {
|
||||
texture = EaglerProfile.customSkins.get(selectedSlot).getResource();
|
||||
}else {
|
||||
} else {
|
||||
texture = DefaultSkins.getSkinFromId(skid).location;
|
||||
}
|
||||
|
||||
|
@ -283,14 +302,14 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
|
||||
public void handleMouseInput() throws IOException {
|
||||
super.handleMouseInput();
|
||||
if(dropDownOpen) {
|
||||
if (dropDownOpen) {
|
||||
int var1 = Mouse.getEventDWheel();
|
||||
if(var1 < 0) {
|
||||
if (var1 < 0) {
|
||||
scrollPos += 3;
|
||||
}
|
||||
if(var1 > 0) {
|
||||
if (var1 > 0) {
|
||||
scrollPos -= 3;
|
||||
if(scrollPos < 0) {
|
||||
if (scrollPos < 0) {
|
||||
scrollPos = 0;
|
||||
}
|
||||
}
|
||||
|
@ -298,14 +317,14 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(!dropDownOpen) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if (!dropDownOpen) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
this.mc.displayGuiScreen((GuiScreen) parent);
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
} else if (par1GuiButton.id == 1) {
|
||||
EagRuntime.displayFileChooser("image/png", "png");
|
||||
}else if(par1GuiButton.id == 2) {
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
EaglerProfile.clearCustomSkins();
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
|
@ -317,66 +336,68 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
|
||||
public void updateScreen() {
|
||||
usernameField.updateCursorCounter();
|
||||
if(EagRuntime.fileChooserHasResult()) {
|
||||
if (EagRuntime.fileChooserHasResult()) {
|
||||
FileChooserResult result = EagRuntime.getFileChooserResult();
|
||||
if(result != null) {
|
||||
if (result != null) {
|
||||
ImageData loadedSkin = ImageData.loadImageFile(result.fileData);
|
||||
if(loadedSkin != null) {
|
||||
if (loadedSkin != null) {
|
||||
boolean isLegacy = loadedSkin.width == 64 && loadedSkin.height == 32;
|
||||
boolean isModern = loadedSkin.width == 64 && loadedSkin.height == 64;
|
||||
if(isLegacy) {
|
||||
if (isLegacy) {
|
||||
ImageData newSkin = new ImageData(64, 64, true);
|
||||
SkinConverter.convert64x32to64x64(loadedSkin, newSkin);
|
||||
loadedSkin = newSkin;
|
||||
isModern = true;
|
||||
}
|
||||
if(isModern) {
|
||||
if (isModern) {
|
||||
byte[] rawSkin = new byte[16384];
|
||||
for(int i = 0, j, k; i < 4096; ++i) {
|
||||
for (int i = 0, j, k; i < 4096; ++i) {
|
||||
j = i << 2;
|
||||
k = loadedSkin.pixels[i];
|
||||
rawSkin[j] = (byte)(k >> 24);
|
||||
rawSkin[j + 1] = (byte)(k >> 16);
|
||||
rawSkin[j + 2] = (byte)(k >> 8);
|
||||
rawSkin[j + 3] = (byte)(k & 0xFF);
|
||||
rawSkin[j] = (byte) (k >> 24);
|
||||
rawSkin[j + 1] = (byte) (k >> 16);
|
||||
rawSkin[j + 2] = (byte) (k >> 8);
|
||||
rawSkin[j + 3] = (byte) (k & 0xFF);
|
||||
}
|
||||
for(int y = 20; y < 32; ++y) {
|
||||
for(int x = 16; x < 40; ++x) {
|
||||
rawSkin[(y << 8) | (x << 2)] = (byte)0xff;
|
||||
for (int y = 20; y < 32; ++y) {
|
||||
for (int x = 16; x < 40; ++x) {
|
||||
rawSkin[(y << 8) | (x << 2)] = (byte) 0xff;
|
||||
}
|
||||
}
|
||||
int k;
|
||||
if((k = EaglerProfile.addCustomSkin(result.fileName, rawSkin)) != -1) {
|
||||
if ((k = EaglerProfile.addCustomSkin(result.fileName, rawSkin)) != -1) {
|
||||
selectedSlot = k;
|
||||
newSkinWaitSteveOrAlex = true;
|
||||
updateOptions();
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
}
|
||||
}else {
|
||||
EagRuntime.showPopup("The selected image '" + result.fileName + "' is not the right size!\nEaglercraft only supports 64x32 or 64x64 skins");
|
||||
} else {
|
||||
EagRuntime.showPopup("The selected image '" + result.fileName
|
||||
+ "' is not the right size!\nEaglercraft only supports 64x32 or 64x64 skins");
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
EagRuntime.showPopup("The selected file '" + result.fileName + "' is not a PNG file!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(dropDownOpen) {
|
||||
if(Mouse.isButtonDown(0)) {
|
||||
if (dropDownOpen) {
|
||||
if (Mouse.isButtonDown(0)) {
|
||||
int skinX = width / 2 - 20;
|
||||
int skinY = height / 6 + 103;
|
||||
int skinWidth = 140;
|
||||
if(mousex >= (skinX + skinWidth - 10) && mousex < (skinX + skinWidth) && mousey >= skinY && mousey < (skinY + skinsHeight)) {
|
||||
if (mousex >= (skinX + skinWidth - 10) && mousex < (skinX + skinWidth) && mousey >= skinY
|
||||
&& mousey < (skinY + skinsHeight)) {
|
||||
dragging = true;
|
||||
}
|
||||
if(dragging) {
|
||||
if (dragging) {
|
||||
int scrollerSize = skinsHeight * slotsVisible / dropDownOptions.length;
|
||||
scrollPos = (mousey - skinY - (scrollerSize / 2)) * dropDownOptions.length / skinsHeight;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
dragging = false;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
dragging = false;
|
||||
}
|
||||
}
|
||||
|
@ -387,58 +408,64 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
|
||||
protected void keyTyped(char c, int k) {
|
||||
usernameField.textboxKeyTyped(c, k);
|
||||
|
||||
|
||||
String text = usernameField.getText();
|
||||
if(text.length() > 16) text = text.substring(0, 16);
|
||||
if (text.length() > 16)
|
||||
text = text.substring(0, 16);
|
||||
text = text.replaceAll("[^A-Za-z0-9]", "_");
|
||||
usernameField.updateText(text);
|
||||
|
||||
if(k == 200 && selectedSlot > 0) {
|
||||
|
||||
if (k == 200 && selectedSlot > 0) {
|
||||
--selectedSlot;
|
||||
scrollPos = selectedSlot - 2;
|
||||
}
|
||||
if(k == 208 && selectedSlot < (dropDownOptions.length - 1)) {
|
||||
if (k == 208 && selectedSlot < (dropDownOptions.length - 1)) {
|
||||
++selectedSlot;
|
||||
scrollPos = selectedSlot - 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void mouseClicked(int mx, int my, int button) {
|
||||
usernameField.mouseClicked(mx, my, button);
|
||||
if (button == 0) {
|
||||
if(!EagRuntime.getConfiguration().isDemo()) {
|
||||
if (!EagRuntime.getConfiguration().isDemo()) {
|
||||
int w = mc.fontRendererObj.getStringWidth(I18n.format("editProfile.importExport"));
|
||||
if(mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12) {
|
||||
if (mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12) {
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
mc.displayGuiScreen(new GuiScreenImportExportProfile(this));
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int skinX, skinY;
|
||||
int skid = selectedSlot - EaglerProfile.customSkins.size();
|
||||
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model : DefaultSkins.getSkinFromId(skid).model;
|
||||
if(selectedSkinModel == SkinModel.STEVE || selectedSkinModel == SkinModel.ALEX || (selectedSkinModel.highPoly != null && !this.mc.gameSettings.enableFNAWSkins)) {
|
||||
skinX = this.width / 2 - 120;
|
||||
skinY = this.height / 6 + 8;
|
||||
String capesText = I18n.format("editProfile.capes");
|
||||
if(mx > skinX - 10 && my > skinY - 16 && mx < skinX + (fontRendererObj.getStringWidth(capesText) * 0.75f) + 10 && my < skinY + 7) {
|
||||
safeProfile();
|
||||
this.mc.displayGuiScreen(new GuiScreenEditCape(this));
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(newSkinWaitSteveOrAlex) {
|
||||
int skinX, skinY;
|
||||
int skid = selectedSlot - EaglerProfile.customSkins.size();
|
||||
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model
|
||||
: DefaultSkins.getSkinFromId(skid).model;
|
||||
if (selectedSkinModel == SkinModel.STEVE || selectedSkinModel == SkinModel.ALEX
|
||||
|| (selectedSkinModel.highPoly != null && !this.mc.gameSettings.enableFNAWSkins)) {
|
||||
skinX = this.width / 2 - 120;
|
||||
skinY = this.height / 6 + 8;
|
||||
String capesText = I18n.format("editProfile.capes");
|
||||
if (mx > skinX - 10 && my > skinY - 16
|
||||
&& mx < skinX + (fontRendererObj.getStringWidth(capesText) * 0.75f) + 10 && my < skinY + 7) {
|
||||
safeProfile();
|
||||
this.mc.displayGuiScreen(new GuiScreenEditCape(this));
|
||||
mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (newSkinWaitSteveOrAlex) {
|
||||
skinX = width / 2 - 90;
|
||||
skinY = height / 4;
|
||||
int skinWidth = 70;
|
||||
int skinHeight = 120;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
if (mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if (selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
newSkinWaitSteveOrAlex = false;
|
||||
EaglerProfile.customSkins.get(selectedSlot).model = SkinModel.STEVE;
|
||||
safeProfile();
|
||||
|
@ -447,21 +474,21 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
skinX = width / 2 + 20;
|
||||
skinY = height / 4;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
if (mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if (selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
EaglerProfile.customSkins.get(selectedSlot).model = SkinModel.ALEX;
|
||||
newSkinWaitSteveOrAlex = false;
|
||||
safeProfile();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}else if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
} else if (selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
skinX = width / 2 - 120;
|
||||
skinY = height / 6 + 18;
|
||||
int skinWidth = 80;
|
||||
int skinHeight = 120;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
if (mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if (selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
newSkinWaitSteveOrAlex = true;
|
||||
return;
|
||||
}
|
||||
|
@ -469,28 +496,29 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
skinX = width / 2 + 140 - 40;
|
||||
skinY = height / 6 + 82;
|
||||
|
||||
if(mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) {
|
||||
|
||||
if (mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) {
|
||||
dropDownOpen = !dropDownOpen;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
skinX = width / 2 - 20;
|
||||
skinY = height / 6 + 82;
|
||||
int skinWidth = 140;
|
||||
int skinHeight = skinsHeight;
|
||||
|
||||
if(!(mx >= skinX && mx < (skinX + skinWidth) && my >= skinY && my < (skinY + skinHeight + 22))) {
|
||||
|
||||
if (!(mx >= skinX && mx < (skinX + skinWidth) && my >= skinY && my < (skinY + skinHeight + 22))) {
|
||||
dragging = false;
|
||||
if(dropDownOpen) {
|
||||
if (dropDownOpen) {
|
||||
dropDownOpen = false;
|
||||
return;
|
||||
}
|
||||
}else if(dropDownOpen && !dragging) {
|
||||
} else if (dropDownOpen && !dragging) {
|
||||
skinY += 21;
|
||||
for(int i = 0; i < slotsVisible; i++) {
|
||||
if(i + scrollPos < dropDownOptions.length) {
|
||||
if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5) && my < (skinY + i * 10 + 15)) {
|
||||
for (int i = 0; i < slotsVisible; i++) {
|
||||
if (i + scrollPos < dropDownOptions.length) {
|
||||
if (mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5)
|
||||
&& my < (skinY + i * 10 + 15)) {
|
||||
selectedSlot = i + scrollPos;
|
||||
dropDownOpen = false;
|
||||
dragging = false;
|
||||
|
@ -502,21 +530,21 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
super.mouseClicked(mx, my, button);
|
||||
}
|
||||
|
||||
|
||||
protected void safeProfile() {
|
||||
int customLen = EaglerProfile.customSkins.size();
|
||||
if(selectedSlot < customLen) {
|
||||
if (selectedSlot < customLen) {
|
||||
EaglerProfile.presetSkinId = -1;
|
||||
EaglerProfile.customSkinId = selectedSlot;
|
||||
}else {
|
||||
} else {
|
||||
EaglerProfile.presetSkinId = selectedSlot - customLen;
|
||||
EaglerProfile.customSkinId = -1;
|
||||
}
|
||||
String name = usernameField.getText().trim();
|
||||
while(name.length() < 3) {
|
||||
while (name.length() < 3) {
|
||||
name = name + "_";
|
||||
}
|
||||
if(name.length() > 16) {
|
||||
if (name.length() > 16) {
|
||||
name = name.substring(0, 16);
|
||||
}
|
||||
EaglerProfile.setName(name);
|
||||
|
|
|
@ -17,16 +17,24 @@ import net.minecraft.network.play.client.C17PacketCustomPayload;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -36,20 +44,21 @@ public class ServerSkinCache {
|
|||
private static final Logger logger = LogManager.getLogger("ServerSkinCache");
|
||||
|
||||
public class SkinCacheEntry {
|
||||
|
||||
|
||||
protected final boolean isPresetSkin;
|
||||
protected final int presetSkinId;
|
||||
protected final CacheCustomSkin customSkin;
|
||||
|
||||
|
||||
protected long lastCacheHit = System.currentTimeMillis();
|
||||
|
||||
protected SkinCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation, SkinModel model) {
|
||||
|
||||
protected SkinCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation,
|
||||
SkinModel model) {
|
||||
this.isPresetSkin = false;
|
||||
this.presetSkinId = -1;
|
||||
this.customSkin = new CacheCustomSkin(textureInstance, resourceLocation, model);
|
||||
ServerSkinCache.this.textureManager.loadTexture(resourceLocation, textureInstance);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use only for the constant for the client player
|
||||
*/
|
||||
|
@ -58,39 +67,39 @@ public class ServerSkinCache {
|
|||
this.presetSkinId = -1;
|
||||
this.customSkin = new CacheCustomSkin(null, resourceLocation, model);
|
||||
}
|
||||
|
||||
|
||||
protected SkinCacheEntry(int presetSkinId) {
|
||||
this.isPresetSkin = true;
|
||||
this.presetSkinId = presetSkinId;
|
||||
this.customSkin = null;
|
||||
}
|
||||
|
||||
|
||||
public ResourceLocation getResourceLocation() {
|
||||
if(isPresetSkin) {
|
||||
if (isPresetSkin) {
|
||||
return DefaultSkins.getSkinFromId(presetSkinId).location;
|
||||
}else {
|
||||
if(customSkin != null) {
|
||||
} else {
|
||||
if (customSkin != null) {
|
||||
return customSkin.resourceLocation;
|
||||
}else {
|
||||
} else {
|
||||
return DefaultSkins.DEFAULT_STEVE.location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SkinModel getSkinModel() {
|
||||
if(isPresetSkin) {
|
||||
if (isPresetSkin) {
|
||||
return DefaultSkins.getSkinFromId(presetSkinId).model;
|
||||
}else {
|
||||
if(customSkin != null) {
|
||||
} else {
|
||||
if (customSkin != null) {
|
||||
return customSkin.model;
|
||||
}else {
|
||||
} else {
|
||||
return DefaultSkins.DEFAULT_STEVE.model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void free() {
|
||||
if(!isPresetSkin) {
|
||||
if (!isPresetSkin) {
|
||||
ServerSkinCache.this.textureManager.deleteTexture(customSkin.resourceLocation);
|
||||
}
|
||||
}
|
||||
|
@ -98,12 +107,13 @@ public class ServerSkinCache {
|
|||
}
|
||||
|
||||
protected static class CacheCustomSkin {
|
||||
|
||||
|
||||
protected final EaglerSkinTexture textureInstance;
|
||||
protected final ResourceLocation resourceLocation;
|
||||
protected final SkinModel model;
|
||||
|
||||
protected CacheCustomSkin(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation, SkinModel model) {
|
||||
|
||||
protected CacheCustomSkin(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation,
|
||||
SkinModel model) {
|
||||
this.textureInstance = textureInstance;
|
||||
this.resourceLocation = resourceLocation;
|
||||
this.model = model;
|
||||
|
@ -112,10 +122,10 @@ public class ServerSkinCache {
|
|||
}
|
||||
|
||||
protected static class WaitingSkin {
|
||||
|
||||
|
||||
protected final long timeout;
|
||||
protected final SkinModel model;
|
||||
|
||||
|
||||
protected WaitingSkin(long timeout, SkinModel model) {
|
||||
this.timeout = timeout;
|
||||
this.model = model;
|
||||
|
@ -131,7 +141,7 @@ public class ServerSkinCache {
|
|||
|
||||
private final EaglercraftNetworkManager networkManager;
|
||||
protected final TextureManager textureManager;
|
||||
|
||||
|
||||
private final EaglercraftUUID clientPlayerId;
|
||||
private final SkinCacheEntry clientPlayerCacheEntry;
|
||||
|
||||
|
@ -145,7 +155,8 @@ public class ServerSkinCache {
|
|||
this.networkManager = networkManager;
|
||||
this.textureManager = textureManager;
|
||||
this.clientPlayerId = EaglerProfile.getPlayerUUID();
|
||||
this.clientPlayerCacheEntry = new SkinCacheEntry(EaglerProfile.getActiveSkinResourceLocation(), EaglerProfile.getActiveSkinModel());
|
||||
this.clientPlayerCacheEntry = new SkinCacheEntry(EaglerProfile.getActiveSkinResourceLocation(),
|
||||
EaglerProfile.getActiveSkinModel());
|
||||
}
|
||||
|
||||
public SkinCacheEntry getClientPlayerSkin() {
|
||||
|
@ -154,27 +165,27 @@ public class ServerSkinCache {
|
|||
|
||||
public SkinCacheEntry getSkin(GameProfile player) {
|
||||
EaglercraftUUID uuid = player.getId();
|
||||
if(uuid != null && uuid.equals(clientPlayerId)) {
|
||||
if (uuid != null && uuid.equals(clientPlayerId)) {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
TexturesProperty props = player.getTextures();
|
||||
if(props.eaglerPlayer || props.skin == null) {
|
||||
if(uuid != null) {
|
||||
if (props.eaglerPlayer || props.skin == null) {
|
||||
if (uuid != null) {
|
||||
return _getSkin(uuid);
|
||||
}else {
|
||||
if("slim".equalsIgnoreCase(props.model)) {
|
||||
} else {
|
||||
if ("slim".equalsIgnoreCase(props.model)) {
|
||||
return defaultSlimCacheEntry;
|
||||
}else {
|
||||
} else {
|
||||
return defaultCacheEntry;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
return getSkin(props.skin, SkinModel.getModelFromId(props.model));
|
||||
}
|
||||
}
|
||||
|
||||
public SkinCacheEntry getSkin(EaglercraftUUID player) {
|
||||
if(player.equals(clientPlayerId)) {
|
||||
if (player.equals(clientPlayerId)) {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
return _getSkin(player);
|
||||
|
@ -182,13 +193,13 @@ public class ServerSkinCache {
|
|||
|
||||
private SkinCacheEntry _getSkin(EaglercraftUUID player) {
|
||||
SkinCacheEntry etr = skinsCache.get(player);
|
||||
if(etr == null) {
|
||||
if(!waitingSkins.containsKey(player) && !evictedSkins.containsKey(player)) {
|
||||
if (etr == null) {
|
||||
if (!waitingSkins.containsKey(player) && !evictedSkins.containsKey(player)) {
|
||||
waitingSkins.put(player, new WaitingSkin(System.currentTimeMillis(), null));
|
||||
PacketBuffer buffer;
|
||||
try {
|
||||
buffer = SkinPackets.writeGetOtherSkin(player);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Could not write skin request packet!");
|
||||
logger.error(ex);
|
||||
return defaultCacheEntry;
|
||||
|
@ -196,28 +207,28 @@ public class ServerSkinCache {
|
|||
networkManager.sendPacket(new C17PacketCustomPayload("EAG|Skins-1.8", buffer));
|
||||
}
|
||||
return defaultCacheEntry;
|
||||
}else {
|
||||
} else {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
return etr;
|
||||
}
|
||||
}
|
||||
|
||||
public SkinCacheEntry getSkin(String url, SkinModel skinModelResponse) {
|
||||
if(url.length() > 0xFFFF) {
|
||||
if (url.length() > 0xFFFF) {
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
}
|
||||
EaglercraftUUID generatedUUID = SkinPackets.createEaglerURLSkinUUID(url);
|
||||
SkinCacheEntry etr = skinsCache.get(generatedUUID);
|
||||
if(etr != null) {
|
||||
if (etr != null) {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
return etr;
|
||||
}else {
|
||||
if(!waitingSkins.containsKey(generatedUUID) && !evictedSkins.containsKey(generatedUUID)) {
|
||||
} else {
|
||||
if (!waitingSkins.containsKey(generatedUUID) && !evictedSkins.containsKey(generatedUUID)) {
|
||||
waitingSkins.put(generatedUUID, new WaitingSkin(System.currentTimeMillis(), skinModelResponse));
|
||||
PacketBuffer buffer;
|
||||
try {
|
||||
buffer = SkinPackets.writeGetSkinByURL(generatedUUID, url);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Could not write skin request packet!");
|
||||
logger.error(ex);
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
|
@ -229,83 +240,84 @@ public class ServerSkinCache {
|
|||
}
|
||||
|
||||
public void cacheSkinPreset(EaglercraftUUID player, int presetId) {
|
||||
if(waitingSkins.remove(player) != null) {
|
||||
if (waitingSkins.remove(player) != null) {
|
||||
SkinCacheEntry etr = skinsCache.remove(player);
|
||||
if(etr != null) {
|
||||
if (etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
skinsCache.put(player, new SkinCacheEntry(presetId));
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Unsolicited skin response recieved for \"{}\"! (preset {})", player, presetId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void cacheSkinCustom(EaglercraftUUID player, byte[] pixels, SkinModel model) {
|
||||
WaitingSkin waitingSkin;
|
||||
if((waitingSkin = waitingSkins.remove(player)) != null) {
|
||||
if ((waitingSkin = waitingSkins.remove(player)) != null) {
|
||||
SkinCacheEntry etr = skinsCache.remove(player);
|
||||
if(etr != null) {
|
||||
if (etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
if(waitingSkin.model != null) {
|
||||
if (waitingSkin.model != null) {
|
||||
model = waitingSkin.model;
|
||||
}else if(model == null) {
|
||||
} else if (model == null) {
|
||||
model = (player.hashCode() & 1) != 0 ? SkinModel.ALEX : SkinModel.STEVE;
|
||||
}
|
||||
try {
|
||||
etr = new SkinCacheEntry(new EaglerSkinTexture(pixels, model.width, model.height),
|
||||
new ResourceLocation("eagler:skins/multiplayer/tex_" + texId++), model);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
etr = new SkinCacheEntry(0);
|
||||
logger.error("Could not process custom skin packet for \"{}\"!", player);
|
||||
logger.error(t);
|
||||
}
|
||||
skinsCache.put(player, etr);
|
||||
}else {
|
||||
logger.error("Unsolicited skin response recieved for \"{}\"! (custom {}x{})", player, model.width, model.height);
|
||||
} else {
|
||||
logger.error("Unsolicited skin response recieved for \"{}\"! (custom {}x{})", player, model.width,
|
||||
model.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SkinModel getRequestedSkinType(EaglercraftUUID waiting) {
|
||||
WaitingSkin waitingSkin;
|
||||
if((waitingSkin = waitingSkins.get(waiting)) != null) {
|
||||
if ((waitingSkin = waitingSkins.get(waiting)) != null) {
|
||||
return waitingSkin.model;
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void flush() {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastFlushReq > 5000l) {
|
||||
if (millis - lastFlushReq > 5000l) {
|
||||
lastFlushReq = millis;
|
||||
if(!waitingSkins.isEmpty()) {
|
||||
if (!waitingSkins.isEmpty()) {
|
||||
Iterator<WaitingSkin> waitingItr = waitingSkins.values().iterator();
|
||||
while(waitingItr.hasNext()) {
|
||||
if(millis - waitingItr.next().timeout > 30000l) {
|
||||
while (waitingItr.hasNext()) {
|
||||
if (millis - waitingItr.next().timeout > 30000l) {
|
||||
waitingItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(millis - lastFlushEvict > 1000l) {
|
||||
if (millis - lastFlushEvict > 1000l) {
|
||||
lastFlushEvict = millis;
|
||||
if(!evictedSkins.isEmpty()) {
|
||||
if (!evictedSkins.isEmpty()) {
|
||||
Iterator<Long> evictItr = evictedSkins.values().iterator();
|
||||
while(evictItr.hasNext()) {
|
||||
if(millis - evictItr.next().longValue() > 3000l) {
|
||||
while (evictItr.hasNext()) {
|
||||
if (millis - evictItr.next().longValue() > 3000l) {
|
||||
evictItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(millis - lastFlush > 60000l) {
|
||||
if (millis - lastFlush > 60000l) {
|
||||
lastFlush = millis;
|
||||
if(!skinsCache.isEmpty()) {
|
||||
if (!skinsCache.isEmpty()) {
|
||||
Iterator<SkinCacheEntry> entryItr = skinsCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
while (entryItr.hasNext()) {
|
||||
SkinCacheEntry etr = entryItr.next();
|
||||
if(millis - etr.lastCacheHit > 900000l) { // 15 minutes
|
||||
if (millis - etr.lastCacheHit > 900000l) { // 15 minutes
|
||||
entryItr.remove();
|
||||
etr.free();
|
||||
}
|
||||
|
@ -313,21 +325,21 @@ public class ServerSkinCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void destroy() {
|
||||
Iterator<SkinCacheEntry> entryItr = skinsCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
while (entryItr.hasNext()) {
|
||||
entryItr.next().free();
|
||||
}
|
||||
skinsCache.clear();
|
||||
waitingSkins.clear();
|
||||
evictedSkins.clear();
|
||||
}
|
||||
|
||||
|
||||
public void evictSkin(EaglercraftUUID uuid) {
|
||||
evictedSkins.put(uuid, Long.valueOf(System.currentTimeMillis()));
|
||||
SkinCacheEntry etr = skinsCache.remove(uuid);
|
||||
if(etr != null) {
|
||||
if (etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8.profile;
|
|||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -37,27 +45,27 @@ public class SkinConverter {
|
|||
|
||||
public static void convertCape32x32RGBAto23x17RGB(ImageData skinIn, byte[] skinOut) {
|
||||
int i, j;
|
||||
for(int y = 0; y < 17; ++y) {
|
||||
for(int x = 0; x < 22; ++x) {
|
||||
for (int y = 0; y < 17; ++y) {
|
||||
for (int x = 0; x < 22; ++x) {
|
||||
i = (y * 23 + x) * 3;
|
||||
j = skinIn.pixels[y * skinIn.width + x];
|
||||
if((j & 0xFF000000) != 0) {
|
||||
skinOut[i] = (byte)(j >> 16);
|
||||
skinOut[i + 1] = (byte)(j >> 8);
|
||||
skinOut[i + 2] = (byte)(j & 0xFF);
|
||||
}else {
|
||||
if ((j & 0xFF000000) != 0) {
|
||||
skinOut[i] = (byte) (j >> 16);
|
||||
skinOut[i + 1] = (byte) (j >> 8);
|
||||
skinOut[i + 2] = (byte) (j & 0xFF);
|
||||
} else {
|
||||
skinOut[i] = skinOut[i + 1] = skinOut[i + 2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int y = 0; y < 11; ++y) {
|
||||
for (int y = 0; y < 11; ++y) {
|
||||
i = ((y + 6) * 23 + 22) * 3;
|
||||
j = skinIn.pixels[(y + 11) * skinIn.width + 22];
|
||||
if((j & 0xFF000000) != 0) {
|
||||
skinOut[i] = (byte)(j >> 16);
|
||||
skinOut[i + 1] = (byte)(j >> 8);
|
||||
skinOut[i + 2] = (byte)(j & 0xFF);
|
||||
}else {
|
||||
if ((j & 0xFF000000) != 0) {
|
||||
skinOut[i] = (byte) (j >> 16);
|
||||
skinOut[i + 1] = (byte) (j >> 8);
|
||||
skinOut[i + 2] = (byte) (j & 0xFF);
|
||||
} else {
|
||||
skinOut[i] = skinOut[i + 1] = skinOut[i + 2] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -65,20 +73,20 @@ public class SkinConverter {
|
|||
|
||||
public static void convertCape23x17RGBto32x32RGBA(byte[] skinIn, byte[] skinOut) {
|
||||
int i, j;
|
||||
for(int y = 0; y < 17; ++y) {
|
||||
for(int x = 0; x < 22; ++x) {
|
||||
for (int y = 0; y < 17; ++y) {
|
||||
for (int x = 0; x < 22; ++x) {
|
||||
i = (y * 32 + x) << 2;
|
||||
j = (y * 23 + x) * 3;
|
||||
skinOut[i] = (byte)0xFF;
|
||||
skinOut[i] = (byte) 0xFF;
|
||||
skinOut[i + 1] = skinIn[j];
|
||||
skinOut[i + 2] = skinIn[j + 1];
|
||||
skinOut[i + 3] = skinIn[j + 2];
|
||||
}
|
||||
}
|
||||
for(int y = 0; y < 11; ++y) {
|
||||
for (int y = 0; y < 11; ++y) {
|
||||
i = ((y + 11) * 32 + 22) << 2;
|
||||
j = ((y + 6) * 23 + 22) * 3;
|
||||
skinOut[i] = (byte)0xFF;
|
||||
skinOut[i] = (byte) 0xFF;
|
||||
skinOut[i + 1] = skinIn[j];
|
||||
skinOut[i + 2] = skinIn[j + 1];
|
||||
skinOut[i + 3] = skinIn[j + 2];
|
||||
|
@ -87,7 +95,7 @@ public class SkinConverter {
|
|||
|
||||
private static void copyRawPixels(int[] imageIn, int[] imageOut, int dx1, int dy1, int dx2, int dy2, int sx1,
|
||||
int sy1, int sx2, int sy2, int imgSrcWidth, int imgDstWidth) {
|
||||
if(dx1 > dx2) {
|
||||
if (dx1 > dx2) {
|
||||
copyRawPixels(imageIn, imageOut, sx1, sy1, dx2, dy1, sx2 - sx1, sy2 - sy1, imgSrcWidth, imgDstWidth, true);
|
||||
} else {
|
||||
copyRawPixels(imageIn, imageOut, sx1, sy1, dx1, dy1, sx2 - sx1, sy2 - sy1, imgSrcWidth, imgDstWidth, false);
|
||||
|
@ -97,12 +105,12 @@ public class SkinConverter {
|
|||
private static void copyRawPixels(int[] imageIn, int[] imageOut, int srcX, int srcY, int dstX, int dstY, int width,
|
||||
int height, int imgSrcWidth, int imgDstWidth, boolean flip) {
|
||||
int i, j;
|
||||
for(int y = 0; y < height; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
i = imageIn[(srcY + y) * imgSrcWidth + srcX + x];
|
||||
if(flip) {
|
||||
if (flip) {
|
||||
j = (dstY + y) * imgDstWidth + dstX + width - x - 1;
|
||||
}else {
|
||||
} else {
|
||||
j = (dstY + y) * imgDstWidth + dstX + x;
|
||||
}
|
||||
imageOut[j] = i;
|
||||
|
|
|
@ -4,16 +4,24 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -23,17 +31,17 @@ public enum SkinModel {
|
|||
LONG_ARMS(3, HighPolySkin.LONG_ARMS), WEIRD_CLIMBER_DUDE(4, HighPolySkin.WEIRD_CLIMBER_DUDE),
|
||||
LAXATIVE_DUDE(5, HighPolySkin.LAXATIVE_DUDE), BABY_CHARLES(6, HighPolySkin.BABY_CHARLES),
|
||||
BABY_WINSTON(7, HighPolySkin.BABY_WINSTON);
|
||||
|
||||
public final int id;
|
||||
|
||||
public final int id;
|
||||
public final int width;
|
||||
public final int height;
|
||||
public final String profileSkinType;
|
||||
public final boolean sanitize;
|
||||
public final HighPolySkin highPoly;
|
||||
|
||||
|
||||
public static final SkinModel[] skinModels = new SkinModel[8];
|
||||
private static final Map<String, SkinModel> skinModelsByName = new HashMap();
|
||||
|
||||
|
||||
private SkinModel(int id, int w, int h, String profileSkinType, boolean sanitize) {
|
||||
this.id = id;
|
||||
this.width = w;
|
||||
|
@ -42,7 +50,7 @@ public enum SkinModel {
|
|||
this.sanitize = sanitize;
|
||||
this.highPoly = null;
|
||||
}
|
||||
|
||||
|
||||
private SkinModel(int id, HighPolySkin highPoly) {
|
||||
this.id = id;
|
||||
this.width = 256;
|
||||
|
@ -54,7 +62,7 @@ public enum SkinModel {
|
|||
|
||||
public static SkinModel getModelFromId(String str) {
|
||||
SkinModel mdl = skinModelsByName.get(str.toLowerCase());
|
||||
if(mdl == null) {
|
||||
if (mdl == null) {
|
||||
return skinModels[0];
|
||||
}
|
||||
return mdl;
|
||||
|
@ -62,19 +70,19 @@ public enum SkinModel {
|
|||
|
||||
public static SkinModel getModelFromId(int id) {
|
||||
SkinModel s = null;
|
||||
if(id >= 0 && id < skinModels.length) {
|
||||
if (id >= 0 && id < skinModels.length) {
|
||||
s = skinModels[id];
|
||||
}
|
||||
if(s != null) {
|
||||
if (s != null) {
|
||||
return s;
|
||||
}else {
|
||||
} else {
|
||||
return STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
SkinModel[] arr = values();
|
||||
for(int i = 0; i < arr.length; ++i) {
|
||||
for (int i = 0; i < arr.length; ++i) {
|
||||
skinModels[arr[i].id] = arr[i];
|
||||
skinModelsByName.put(arr[i].profileSkinType, arr[i]);
|
||||
}
|
||||
|
|
|
@ -9,16 +9,24 @@ import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
|
|||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -35,47 +43,49 @@ public class SkinPackets {
|
|||
|
||||
public static void readPluginMessage(PacketBuffer buffer, ServerSkinCache skinCache) throws IOException {
|
||||
try {
|
||||
int type = (int)buffer.readByte() & 0xFF;
|
||||
switch(type) {
|
||||
case PACKET_OTHER_SKIN_PRESET: {
|
||||
EaglercraftUUID responseUUID = buffer.readUuid();
|
||||
int responsePreset = buffer.readInt();
|
||||
if(buffer.isReadable()) {
|
||||
throw new IOException("PACKET_OTHER_SKIN_PRESET had " + buffer.readableBytes() + " remaining bytes!");
|
||||
int type = (int) buffer.readByte() & 0xFF;
|
||||
switch (type) {
|
||||
case PACKET_OTHER_SKIN_PRESET: {
|
||||
EaglercraftUUID responseUUID = buffer.readUuid();
|
||||
int responsePreset = buffer.readInt();
|
||||
if (buffer.isReadable()) {
|
||||
throw new IOException(
|
||||
"PACKET_OTHER_SKIN_PRESET had " + buffer.readableBytes() + " remaining bytes!");
|
||||
}
|
||||
skinCache.cacheSkinPreset(responseUUID, responsePreset);
|
||||
break;
|
||||
}
|
||||
skinCache.cacheSkinPreset(responseUUID, responsePreset);
|
||||
break;
|
||||
}
|
||||
case PACKET_OTHER_SKIN_CUSTOM: {
|
||||
EaglercraftUUID responseUUID = buffer.readUuid();
|
||||
int model = (int)buffer.readByte() & 0xFF;
|
||||
SkinModel modelId;
|
||||
if(model == (byte)0xFF) {
|
||||
modelId = skinCache.getRequestedSkinType(responseUUID);
|
||||
}else {
|
||||
modelId = SkinModel.getModelFromId(model & 0x7F);
|
||||
if((model & 0x80) != 0 && modelId.sanitize) {
|
||||
case PACKET_OTHER_SKIN_CUSTOM: {
|
||||
EaglercraftUUID responseUUID = buffer.readUuid();
|
||||
int model = (int) buffer.readByte() & 0xFF;
|
||||
SkinModel modelId;
|
||||
if (model == (byte) 0xFF) {
|
||||
modelId = skinCache.getRequestedSkinType(responseUUID);
|
||||
} else {
|
||||
modelId = SkinModel.getModelFromId(model & 0x7F);
|
||||
if ((model & 0x80) != 0 && modelId.sanitize) {
|
||||
modelId = SkinModel.STEVE;
|
||||
}
|
||||
}
|
||||
if (modelId.highPoly != null) {
|
||||
modelId = SkinModel.STEVE;
|
||||
}
|
||||
int bytesToRead = modelId.width * modelId.height * 4;
|
||||
byte[] readSkin = new byte[bytesToRead];
|
||||
buffer.readBytes(readSkin);
|
||||
if (buffer.isReadable()) {
|
||||
throw new IOException(
|
||||
"PACKET_MY_SKIN_CUSTOM had " + buffer.readableBytes() + " remaining bytes!");
|
||||
}
|
||||
skinCache.cacheSkinCustom(responseUUID, readSkin, modelId);
|
||||
break;
|
||||
}
|
||||
if(modelId.highPoly != null) {
|
||||
modelId = SkinModel.STEVE;
|
||||
}
|
||||
int bytesToRead = modelId.width * modelId.height * 4;
|
||||
byte[] readSkin = new byte[bytesToRead];
|
||||
buffer.readBytes(readSkin);
|
||||
if(buffer.isReadable()) {
|
||||
throw new IOException("PACKET_MY_SKIN_CUSTOM had " + buffer.readableBytes() + " remaining bytes!");
|
||||
}
|
||||
skinCache.cacheSkinCustom(responseUUID, readSkin, modelId);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unknown skin packet type: " + type);
|
||||
}
|
||||
default:
|
||||
throw new IOException("Unknown skin packet type: " + type);
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw ex;
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new IOException("Failed to parse skin packet!", t);
|
||||
}
|
||||
}
|
||||
|
@ -115,12 +125,12 @@ public class SkinPackets {
|
|||
ret.writeByte(PACKET_GET_SKIN_BY_URL);
|
||||
ret.writeUuid(skinId);
|
||||
byte[] url = ArrayUtils.asciiString(skinUrl);
|
||||
ret.writeShort((int)url.length);
|
||||
ret.writeShort((int) url.length);
|
||||
ret.writeBytes(url);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static EaglercraftUUID createEaglerURLSkinUUID(String skinUrl){
|
||||
public static EaglercraftUUID createEaglerURLSkinUUID(String skinUrl) {
|
||||
MD5Digest dg = new MD5Digest();
|
||||
byte[] bytes = ArrayUtils.asciiString("EaglercraftSkinURL:" + skinUrl);
|
||||
dg.update(bytes, 0, bytes.length);
|
||||
|
|
|
@ -11,16 +11,24 @@ import net.minecraft.client.renderer.RenderHelper;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -30,7 +38,7 @@ public class SkinPreviewRenderer {
|
|||
private static ModelPlayer playerModelSteve = null;
|
||||
private static ModelPlayer playerModelAlex = null;
|
||||
private static ModelZombie playerModelZombie = null;
|
||||
|
||||
|
||||
public static void initialize() {
|
||||
playerModelSteve = new ModelPlayer(0.0f, false);
|
||||
playerModelSteve.isChild = false;
|
||||
|
@ -44,72 +52,74 @@ public class SkinPreviewRenderer {
|
|||
renderPreview(x, y, mx, my, false, skinModel, null, null);
|
||||
}
|
||||
|
||||
public static void renderPreview(int x, int y, int mx, int my, boolean capeMode, SkinModel skinModel, ResourceLocation skinTexture, ResourceLocation capeTexture) {
|
||||
public static void renderPreview(int x, int y, int mx, int my, boolean capeMode, SkinModel skinModel,
|
||||
ResourceLocation skinTexture, ResourceLocation capeTexture) {
|
||||
ModelBiped model;
|
||||
switch(skinModel) {
|
||||
case STEVE:
|
||||
default:
|
||||
model = playerModelSteve;
|
||||
break;
|
||||
case ALEX:
|
||||
model = playerModelAlex;
|
||||
break;
|
||||
case ZOMBIE:
|
||||
model = playerModelZombie;
|
||||
break;
|
||||
case LONG_ARMS:
|
||||
case WEIRD_CLIMBER_DUDE:
|
||||
case LAXATIVE_DUDE:
|
||||
case BABY_CHARLES:
|
||||
case BABY_WINSTON:
|
||||
if(skinModel.highPoly != null && Minecraft.getMinecraft().gameSettings.enableFNAWSkins) {
|
||||
renderHighPoly(x, y, mx, my, skinModel.highPoly);
|
||||
return;
|
||||
}
|
||||
model = playerModelSteve;
|
||||
break;
|
||||
switch (skinModel) {
|
||||
case STEVE:
|
||||
default:
|
||||
model = playerModelSteve;
|
||||
break;
|
||||
case ALEX:
|
||||
model = playerModelAlex;
|
||||
break;
|
||||
case ZOMBIE:
|
||||
model = playerModelZombie;
|
||||
break;
|
||||
case LONG_ARMS:
|
||||
case WEIRD_CLIMBER_DUDE:
|
||||
case LAXATIVE_DUDE:
|
||||
case BABY_CHARLES:
|
||||
case BABY_WINSTON:
|
||||
if (skinModel.highPoly != null && Minecraft.getMinecraft().gameSettings.enableFNAWSkins) {
|
||||
renderHighPoly(x, y, mx, my, skinModel.highPoly);
|
||||
return;
|
||||
}
|
||||
model = playerModelSteve;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.enableTexture2D();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.disableCull();
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(x, y - 80.0f, 100.0f);
|
||||
GlStateManager.scale(50.0f, 50.0f, 50.0f);
|
||||
GlStateManager.rotate(180.0f, 1.0f, 0.0f, 0.0f);
|
||||
GlStateManager.scale(1.0f, -1.0f, 1.0f);
|
||||
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
|
||||
GlStateManager.translate(0.0f, 1.0f, 0.0f);
|
||||
if(capeMode) {
|
||||
if (capeMode) {
|
||||
GlStateManager.rotate(140.0f, 0.0f, 1.0f, 0.0f);
|
||||
mx = x - (x - mx) - 20;
|
||||
GlStateManager.rotate(((y - my) * -0.02f), 1.0f, 0.0f, 0.0f);
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.rotate(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
GlStateManager.rotate(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.translate(0.0f, -1.0f, 0.0f);
|
||||
|
||||
if(skinTexture != null) {
|
||||
|
||||
if (skinTexture != null) {
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(skinTexture);
|
||||
}
|
||||
|
||||
model.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625f);
|
||||
|
||||
if(capeTexture != null && model instanceof ModelPlayer) {
|
||||
|
||||
model.render(null, 0.0f, 0.0f, (float) (System.currentTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f),
|
||||
((y - my) * -0.1f), 0.0625f);
|
||||
|
||||
if (capeTexture != null && model instanceof ModelPlayer) {
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(capeTexture);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0F, 0.0F, 0.125F);
|
||||
GlStateManager.rotate(6.0F, 1.0F, 0.0F, 0.0F);
|
||||
GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F);
|
||||
((ModelPlayer)model).renderCape(0.0625f);
|
||||
((ModelPlayer) model).renderCape(0.0625f);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.disableLighting();
|
||||
}
|
||||
|
@ -119,55 +129,55 @@ public class SkinPreviewRenderer {
|
|||
GlStateManager.disableBlend();
|
||||
GlStateManager.disableCull();
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(x, y - 80.0f, 100.0f);
|
||||
GlStateManager.scale(50.0f, 50.0f, 50.0f);
|
||||
GlStateManager.rotate(180.0f, 1.0f, 0.0f, 0.0f);
|
||||
GlStateManager.scale(1.0f, -1.0f, 1.0f);
|
||||
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
|
||||
GlStateManager.translate(0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.rotate(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f);
|
||||
GlStateManager.rotate(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.rotate(180.0f, 0.0f, 0.0f, 1.0f);
|
||||
GlStateManager.translate(0.0f, -0.6f, 0.0f);
|
||||
|
||||
|
||||
GlStateManager.scale(HighPolySkin.highPolyScale, HighPolySkin.highPolyScale, HighPolySkin.highPolyScale);
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(msh.texture);
|
||||
|
||||
if(msh.bodyModel != null) {
|
||||
|
||||
if (msh.bodyModel != null) {
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(msh.bodyModel));
|
||||
}
|
||||
|
||||
if(msh.headModel != null) {
|
||||
|
||||
if (msh.headModel != null) {
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(msh.headModel));
|
||||
}
|
||||
|
||||
if(msh.limbsModel != null && msh.limbsModel.length > 0) {
|
||||
for(int i = 0; i < msh.limbsModel.length; ++i) {
|
||||
|
||||
if (msh.limbsModel != null && msh.limbsModel.length > 0) {
|
||||
for (int i = 0; i < msh.limbsModel.length; ++i) {
|
||||
float offset = 0.0f;
|
||||
if(msh.limbsOffset != null) {
|
||||
if(msh.limbsOffset.length == 1) {
|
||||
if (msh.limbsOffset != null) {
|
||||
if (msh.limbsOffset.length == 1) {
|
||||
offset = msh.limbsOffset[0];
|
||||
}else {
|
||||
} else {
|
||||
offset = msh.limbsOffset[i];
|
||||
}
|
||||
}
|
||||
if(offset != 0.0f || msh.limbsInitialRotation != 0.0f) {
|
||||
if (offset != 0.0f || msh.limbsInitialRotation != 0.0f) {
|
||||
GlStateManager.pushMatrix();
|
||||
if(offset != 0.0f) {
|
||||
if (offset != 0.0f) {
|
||||
GlStateManager.translate(0.0f, offset, 0.0f);
|
||||
}
|
||||
if(msh.limbsInitialRotation != 0.0f) {
|
||||
if (msh.limbsInitialRotation != 0.0f) {
|
||||
GlStateManager.rotate(msh.limbsInitialRotation, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(msh.limbsModel[i]));
|
||||
|
||||
if(offset != 0.0f || msh.limbsInitialRotation != 0.0f) {
|
||||
|
||||
if (offset != 0.0f || msh.limbsInitialRotation != 0.0f) {
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,24 @@ import net.minecraft.client.multiplayer.ServerAddress;
|
|||
import net.minecraft.client.multiplayer.ServerData;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -24,13 +32,13 @@ public class AddressResolver {
|
|||
public static String resolveURI(ServerData input) {
|
||||
return resolveURI(input.serverIP);
|
||||
}
|
||||
|
||||
|
||||
public static String resolveURI(String input) {
|
||||
String lc = input.toLowerCase();
|
||||
if(!lc.startsWith("ws://") && !lc.startsWith("wss://")) {
|
||||
if(EagRuntime.requireSSL()) {
|
||||
if (!lc.startsWith("ws://") && !lc.startsWith("wss://")) {
|
||||
if (EagRuntime.requireSSL()) {
|
||||
input = "wss://" + input;
|
||||
}else {
|
||||
} else {
|
||||
input = "ws://" + input;
|
||||
}
|
||||
}
|
||||
|
@ -40,24 +48,24 @@ public class AddressResolver {
|
|||
public static ServerAddress resolveAddressFromURI(String input) {
|
||||
String uri = resolveURI(input);
|
||||
String lc = input.toLowerCase();
|
||||
if(lc.startsWith("ws://")) {
|
||||
if (lc.startsWith("ws://")) {
|
||||
input = input.substring(5);
|
||||
}else if(lc.startsWith("wss://")) {
|
||||
} else if (lc.startsWith("wss://")) {
|
||||
input = input.substring(6);
|
||||
}
|
||||
int port = EagRuntime.requireSSL() ? 443: 80;
|
||||
int port = EagRuntime.requireSSL() ? 443 : 80;
|
||||
int i = input.indexOf('/');
|
||||
if(i != -1) {
|
||||
if (i != -1) {
|
||||
input = input.substring(0, i);
|
||||
}
|
||||
i = input.lastIndexOf(':');
|
||||
if(i != -1) {
|
||||
if (i != -1) {
|
||||
try {
|
||||
port = Integer.parseInt(input.substring(i + 1));
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
return new ServerAddress(uri, port);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.socket;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -22,5 +30,5 @@ public class CompressionNotSupportedException extends UnsupportedOperationExcept
|
|||
"'network-compression-threshold=-1' in server.properties to " +
|
||||
"allow Eaglercraft connections to this server");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,16 +28,24 @@ import net.minecraft.util.EnumChatFormatting;
|
|||
import net.minecraft.util.IChatComponent;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -48,247 +56,255 @@ public class ConnectionHandshake {
|
|||
|
||||
private static final int protocolV2 = 2;
|
||||
private static final int protocolV3 = 3;
|
||||
|
||||
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
||||
public static String pluginVersion = null;
|
||||
public static String pluginBrand = null;
|
||||
|
||||
public static boolean attemptHandshake(Minecraft mc, GuiConnecting connecting, GuiScreen ret, String password, boolean allowPlaintext) {
|
||||
|
||||
public static boolean attemptHandshake(Minecraft mc, GuiConnecting connecting, GuiScreen ret, String password,
|
||||
boolean allowPlaintext) {
|
||||
try {
|
||||
pluginVersion = null;
|
||||
pluginBrand = null;
|
||||
EaglerOutputStream bao = new EaglerOutputStream();
|
||||
DataOutputStream d = new DataOutputStream(bao);
|
||||
|
||||
|
||||
d.writeByte(HandshakePacketTypes.PROTOCOL_CLIENT_VERSION);
|
||||
|
||||
|
||||
d.writeByte(2); // legacy protocol version
|
||||
|
||||
|
||||
d.writeShort(2); // supported eagler protocols count
|
||||
d.writeShort(protocolV2); // client supports v2
|
||||
d.writeShort(protocolV3); // client supports v3
|
||||
|
||||
d.writeShort(1); // supported game protocols count
|
||||
d.writeShort(47); // client supports 1.8 protocol
|
||||
|
||||
|
||||
String clientBrand = EaglercraftVersion.projectForkName;
|
||||
d.writeByte(clientBrand.length());
|
||||
d.writeBytes(clientBrand);
|
||||
|
||||
|
||||
String clientVers = EaglercraftVersion.projectOriginVersion;
|
||||
d.writeByte(clientVers.length());
|
||||
d.writeBytes(clientVers);
|
||||
|
||||
|
||||
d.writeBoolean(password != null);
|
||||
|
||||
|
||||
String username = mc.getSession().getProfile().getName();
|
||||
d.writeByte(username.length());
|
||||
d.writeBytes(username);
|
||||
|
||||
|
||||
PlatformNetworking.writePlayPacket(bao.toByteArray());
|
||||
|
||||
|
||||
byte[] read = awaitNextPacket(baseTimeout);
|
||||
if(read == null) {
|
||||
if (read == null) {
|
||||
logger.error("Read timed out while waiting for server protocol response!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
DataInputStream di = new DataInputStream(new EaglerInputStream(read));
|
||||
|
||||
|
||||
int type = di.read();
|
||||
if(type == HandshakePacketTypes.PROTOCOL_VERSION_MISMATCH) {
|
||||
|
||||
if (type == HandshakePacketTypes.PROTOCOL_VERSION_MISMATCH) {
|
||||
|
||||
StringBuilder protocols = new StringBuilder();
|
||||
int c = di.readShort();
|
||||
for(int i = 0; i < c; ++i) {
|
||||
if(i > 0) {
|
||||
for (int i = 0; i < c; ++i) {
|
||||
if (i > 0) {
|
||||
protocols.append(", ");
|
||||
}
|
||||
protocols.append("v").append(di.readShort());
|
||||
}
|
||||
|
||||
|
||||
StringBuilder games = new StringBuilder();
|
||||
c = di.readShort();
|
||||
for(int i = 0; i < c; ++i) {
|
||||
if(i > 0) {
|
||||
for (int i = 0; i < c; ++i) {
|
||||
if (i > 0) {
|
||||
games.append(", ");
|
||||
}
|
||||
games.append("mc").append(di.readShort());
|
||||
}
|
||||
|
||||
|
||||
logger.info("Incompatible client: v2 & mc47");
|
||||
logger.info("Server supports: {}", protocols);
|
||||
logger.info("Server supports: {}", games);
|
||||
|
||||
|
||||
int msgLen = di.read();
|
||||
byte[] dat = new byte[msgLen];
|
||||
di.read(dat);
|
||||
String msg = new String(dat, StandardCharsets.UTF_8);
|
||||
|
||||
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed", new ChatComponentText(msg)));
|
||||
|
||||
|
||||
return false;
|
||||
}else if(type == HandshakePacketTypes.PROTOCOL_SERVER_VERSION) {
|
||||
} else if (type == HandshakePacketTypes.PROTOCOL_SERVER_VERSION) {
|
||||
int serverVers = di.readShort();
|
||||
|
||||
if(serverVers != protocolV2 && serverVers != protocolV3) {
|
||||
|
||||
if (serverVers != protocolV2 && serverVers != protocolV3) {
|
||||
logger.info("Incompatible server version: {}", serverVers);
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed", new ChatComponentText(serverVers < protocolV2 ? "Outdated Server" : "Outdated Client")));
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed",
|
||||
new ChatComponentText(serverVers < protocolV2 ? "Outdated Server" : "Outdated Client")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int gameVers = di.readShort();
|
||||
if(gameVers != 47) {
|
||||
if (gameVers != 47) {
|
||||
logger.info("Incompatible minecraft protocol version: {}", gameVers);
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed", new ChatComponentText("This server does not support 1.8!")));
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed",
|
||||
new ChatComponentText("This server does not support 1.8!")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
logger.info("Server protocol: {}", serverVers);
|
||||
|
||||
|
||||
int msgLen = di.read();
|
||||
byte[] dat = new byte[msgLen];
|
||||
di.read(dat);
|
||||
pluginBrand = ArrayUtils.asciiString(dat);
|
||||
|
||||
|
||||
msgLen = di.read();
|
||||
dat = new byte[msgLen];
|
||||
di.read(dat);
|
||||
pluginVersion = ArrayUtils.asciiString(dat);
|
||||
|
||||
|
||||
logger.info("Server version: {}", pluginVersion);
|
||||
logger.info("Server brand: {}", pluginBrand);
|
||||
|
||||
|
||||
int authType = di.read();
|
||||
int saltLength = (int)di.readShort() & 0xFFFF;
|
||||
|
||||
int saltLength = (int) di.readShort() & 0xFFFF;
|
||||
|
||||
byte[] salt = new byte[saltLength];
|
||||
di.read(salt);
|
||||
|
||||
|
||||
bao.reset();
|
||||
d.writeByte(HandshakePacketTypes.PROTOCOL_CLIENT_REQUEST_LOGIN);
|
||||
|
||||
|
||||
d.writeByte(username.length());
|
||||
d.writeBytes(username);
|
||||
|
||||
|
||||
String requestedServer = "default";
|
||||
d.writeByte(requestedServer.length());
|
||||
d.writeBytes(requestedServer);
|
||||
|
||||
if(authType != 0 && password != null && password.length() > 0) {
|
||||
if(authType == HandshakePacketTypes.AUTH_METHOD_PLAINTEXT) {
|
||||
if(allowPlaintext) {
|
||||
|
||||
if (authType != 0 && password != null && password.length() > 0) {
|
||||
if (authType == HandshakePacketTypes.AUTH_METHOD_PLAINTEXT) {
|
||||
if (allowPlaintext) {
|
||||
logger.warn("Server is using insecure plaintext authentication");
|
||||
d.writeByte(password.length() << 1);
|
||||
d.writeChars(password);
|
||||
}else {
|
||||
logger.error("Plaintext authentication was attempted but no user confirmation has been given to proceed");
|
||||
} else {
|
||||
logger.error(
|
||||
"Plaintext authentication was attempted but no user confirmation has been given to proceed");
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed",
|
||||
new ChatComponentText(EnumChatFormatting.RED + "Plaintext authentication was attempted but no user confirmation has been given to proceed")));
|
||||
new ChatComponentText(EnumChatFormatting.RED
|
||||
+ "Plaintext authentication was attempted but no user confirmation has been given to proceed")));
|
||||
return false;
|
||||
}
|
||||
}else if(authType == HandshakePacketTypes.AUTH_METHOD_EAGLER_SHA256) {
|
||||
} else if (authType == HandshakePacketTypes.AUTH_METHOD_EAGLER_SHA256) {
|
||||
SHA256Digest digest = new SHA256Digest();
|
||||
|
||||
|
||||
int passLen = password.length();
|
||||
|
||||
digest.update((byte)((passLen >> 8) & 0xFF));
|
||||
digest.update((byte)(passLen & 0xFF));
|
||||
|
||||
for(int i = 0; i < passLen; ++i) {
|
||||
|
||||
digest.update((byte) ((passLen >> 8) & 0xFF));
|
||||
digest.update((byte) (passLen & 0xFF));
|
||||
|
||||
for (int i = 0; i < passLen; ++i) {
|
||||
char codePoint = password.charAt(i);
|
||||
digest.update((byte)((codePoint >> 8) & 0xFF));
|
||||
digest.update((byte)(codePoint & 0xFF));
|
||||
digest.update((byte) ((codePoint >> 8) & 0xFF));
|
||||
digest.update((byte) (codePoint & 0xFF));
|
||||
}
|
||||
|
||||
|
||||
digest.update(HandshakePacketTypes.EAGLER_SHA256_SALT_SAVE, 0, 32);
|
||||
|
||||
|
||||
byte[] hashed = new byte[32];
|
||||
digest.doFinal(hashed, 0);
|
||||
|
||||
|
||||
digest.reset();
|
||||
|
||||
|
||||
digest.update(hashed, 0, 32);
|
||||
digest.update(salt, 0, 32);
|
||||
digest.update(HandshakePacketTypes.EAGLER_SHA256_SALT_BASE, 0, 32);
|
||||
|
||||
|
||||
digest.doFinal(hashed, 0);
|
||||
|
||||
|
||||
digest.reset();
|
||||
|
||||
|
||||
digest.update(hashed, 0, 32);
|
||||
digest.update(salt, 32, 32);
|
||||
digest.update(HandshakePacketTypes.EAGLER_SHA256_SALT_BASE, 0, 32);
|
||||
|
||||
|
||||
digest.doFinal(hashed, 0);
|
||||
|
||||
|
||||
d.writeByte(32);
|
||||
d.write(hashed);
|
||||
}else if(authType == HandshakePacketTypes.AUTH_METHOD_AUTHME_SHA256) {
|
||||
} else if (authType == HandshakePacketTypes.AUTH_METHOD_AUTHME_SHA256) {
|
||||
SHA256Digest digest = new SHA256Digest();
|
||||
|
||||
|
||||
byte[] passwd = password.getBytes(StandardCharsets.UTF_8);
|
||||
digest.update(passwd, 0, passwd.length);
|
||||
|
||||
|
||||
byte[] hashed = new byte[32];
|
||||
digest.doFinal(hashed, 0);
|
||||
|
||||
|
||||
byte[] toHexAndSalt = new byte[64];
|
||||
for(int i = 0; i < 32; ++i) {
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
toHexAndSalt[i << 1] = HEX[(hashed[i] >> 4) & 0xF];
|
||||
toHexAndSalt[(i << 1) + 1] = HEX[hashed[i] & 0xF];
|
||||
}
|
||||
|
||||
|
||||
digest.reset();
|
||||
digest.update(toHexAndSalt, 0, 64);
|
||||
digest.update(salt, 0, salt.length);
|
||||
|
||||
|
||||
digest.doFinal(hashed, 0);
|
||||
|
||||
for(int i = 0; i < 32; ++i) {
|
||||
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
toHexAndSalt[i << 1] = HEX[(hashed[i] >> 4) & 0xF];
|
||||
toHexAndSalt[(i << 1) + 1] = HEX[hashed[i] & 0xF];
|
||||
}
|
||||
|
||||
d.writeByte(64);
|
||||
d.write(toHexAndSalt);
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Unsupported authentication type: {}", authType);
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed",
|
||||
new ChatComponentText(EnumChatFormatting.RED + "Unsupported authentication type: " + authType + "\n\n" + EnumChatFormatting.GRAY + "(Use a newer version of the client)")));
|
||||
new ChatComponentText(
|
||||
EnumChatFormatting.RED + "Unsupported authentication type: " + authType + "\n\n"
|
||||
+ EnumChatFormatting.GRAY + "(Use a newer version of the client)")));
|
||||
return false;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
d.writeByte(0);
|
||||
}
|
||||
|
||||
|
||||
PlatformNetworking.writePlayPacket(bao.toByteArray());
|
||||
|
||||
|
||||
read = awaitNextPacket(baseTimeout);
|
||||
if(read == null) {
|
||||
if (read == null) {
|
||||
logger.error("Read timed out while waiting for login negotiation response!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
di = new DataInputStream(new EaglerInputStream(read));
|
||||
type = di.read();
|
||||
if(type == HandshakePacketTypes.PROTOCOL_SERVER_ALLOW_LOGIN) {
|
||||
if (type == HandshakePacketTypes.PROTOCOL_SERVER_ALLOW_LOGIN) {
|
||||
msgLen = di.read();
|
||||
dat = new byte[msgLen];
|
||||
di.read(dat);
|
||||
|
||||
|
||||
String serverUsername = ArrayUtils.asciiString(dat);
|
||||
|
||||
Minecraft.getMinecraft().getSession().update(serverUsername, new EaglercraftUUID(di.readLong(), di.readLong()));
|
||||
|
||||
|
||||
Minecraft.getMinecraft().getSession().update(serverUsername,
|
||||
new EaglercraftUUID(di.readLong(), di.readLong()));
|
||||
|
||||
bao.reset();
|
||||
d.writeByte(HandshakePacketTypes.PROTOCOL_CLIENT_PROFILE_DATA);
|
||||
String profileDataType = "skin_v1";
|
||||
d.writeByte(profileDataType.length());
|
||||
d.writeBytes(profileDataType);
|
||||
byte[] packetSkin = EaglerProfile.getSkinPacket();
|
||||
if(packetSkin.length > 0xFFFF) {
|
||||
if (packetSkin.length > 0xFFFF) {
|
||||
throw new IOException("Skin packet is too long: " + packetSkin.length);
|
||||
}
|
||||
d.writeShort(packetSkin.length);
|
||||
|
@ -301,91 +317,93 @@ public class ConnectionHandshake {
|
|||
d.writeByte(profileDataType.length());
|
||||
d.writeBytes(profileDataType);
|
||||
byte[] packetCape = EaglerProfile.getCapePacket();
|
||||
if(packetCape.length > 0xFFFF) {
|
||||
if (packetCape.length > 0xFFFF) {
|
||||
throw new IOException("Cape packet is too long: " + packetCape.length);
|
||||
}
|
||||
d.writeShort(packetCape.length);
|
||||
d.write(packetCape);
|
||||
PlatformNetworking.writePlayPacket(bao.toByteArray());
|
||||
|
||||
|
||||
byte[] packetSignatureData = UpdateService.getClientSignatureData();
|
||||
if(packetSignatureData != null) {
|
||||
if (packetSignatureData != null) {
|
||||
bao.reset();
|
||||
d.writeByte(HandshakePacketTypes.PROTOCOL_CLIENT_PROFILE_DATA);
|
||||
profileDataType = "update_cert_v1";
|
||||
d.writeByte(profileDataType.length());
|
||||
d.writeBytes(profileDataType);
|
||||
if(packetSignatureData.length > 0xFFFF) {
|
||||
throw new IOException("Update certificate login packet is too long: " + packetSignatureData.length);
|
||||
if (packetSignatureData.length > 0xFFFF) {
|
||||
throw new IOException(
|
||||
"Update certificate login packet is too long: " + packetSignatureData.length);
|
||||
}
|
||||
d.writeShort(packetSignatureData.length);
|
||||
d.write(packetSignatureData);
|
||||
PlatformNetworking.writePlayPacket(bao.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
bao.reset();
|
||||
d.writeByte(HandshakePacketTypes.PROTOCOL_CLIENT_FINISH_LOGIN);
|
||||
PlatformNetworking.writePlayPacket(bao.toByteArray());
|
||||
|
||||
|
||||
read = awaitNextPacket(baseTimeout);
|
||||
if(read == null) {
|
||||
if (read == null) {
|
||||
logger.error("Read timed out while waiting for login confirmation response!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
di = new DataInputStream(new EaglerInputStream(read));
|
||||
type = di.read();
|
||||
if(type == HandshakePacketTypes.PROTOCOL_SERVER_FINISH_LOGIN) {
|
||||
if (type == HandshakePacketTypes.PROTOCOL_SERVER_FINISH_LOGIN) {
|
||||
return true;
|
||||
}else if(type == HandshakePacketTypes.PROTOCOL_SERVER_ERROR) {
|
||||
} else if (type == HandshakePacketTypes.PROTOCOL_SERVER_ERROR) {
|
||||
showError(mc, connecting, ret, di, serverVers == protocolV2);
|
||||
return false;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}else if(type == HandshakePacketTypes.PROTOCOL_SERVER_DENY_LOGIN) {
|
||||
if(serverVers == protocolV2) {
|
||||
} else if (type == HandshakePacketTypes.PROTOCOL_SERVER_DENY_LOGIN) {
|
||||
if (serverVers == protocolV2) {
|
||||
msgLen = di.read();
|
||||
}else {
|
||||
} else {
|
||||
msgLen = di.readUnsignedShort();
|
||||
}
|
||||
dat = new byte[msgLen];
|
||||
di.read(dat);
|
||||
String errStr = new String(dat, StandardCharsets.UTF_8);
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed", IChatComponent.Serializer.jsonToComponent(errStr)));
|
||||
mc.displayGuiScreen(new GuiDisconnected(ret, "connect.failed",
|
||||
IChatComponent.Serializer.jsonToComponent(errStr)));
|
||||
return false;
|
||||
}else if(type == HandshakePacketTypes.PROTOCOL_SERVER_ERROR) {
|
||||
} else if (type == HandshakePacketTypes.PROTOCOL_SERVER_ERROR) {
|
||||
showError(mc, connecting, ret, di, serverVers == protocolV2);
|
||||
return false;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}else if(type == HandshakePacketTypes.PROTOCOL_SERVER_ERROR) {
|
||||
} else if (type == HandshakePacketTypes.PROTOCOL_SERVER_ERROR) {
|
||||
showError(mc, connecting, ret, di, true);
|
||||
return false;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Exception in handshake");
|
||||
logger.error(t);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static byte[] awaitNextPacket(long timeout) {
|
||||
long millis = System.currentTimeMillis();
|
||||
byte[] b;
|
||||
while((b = PlatformNetworking.readPlayPacket()) == null) {
|
||||
if(PlatformNetworking.playConnectionState().isClosed()) {
|
||||
while ((b = PlatformNetworking.readPlayPacket()) == null) {
|
||||
if (PlatformNetworking.playConnectionState().isClosed()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(50l);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
if(System.currentTimeMillis() - millis > timeout) {
|
||||
if (System.currentTimeMillis() - millis > timeout) {
|
||||
PlatformNetworking.playDisconnect();
|
||||
return null;
|
||||
}
|
||||
|
@ -395,49 +413,55 @@ public class ConnectionHandshake {
|
|||
|
||||
@JSBody(params = {}, script = "window.onbeforeunload = null; location.reload();")
|
||||
public static native void reloadPage();
|
||||
|
||||
private static void showError(Minecraft mc, GuiConnecting connecting, GuiScreen scr, DataInputStream err, boolean v2) throws IOException {
|
||||
|
||||
private static void showError(Minecraft mc, GuiConnecting connecting, GuiScreen scr, DataInputStream err,
|
||||
boolean v2) throws IOException {
|
||||
int errorCode = err.read();
|
||||
int msgLen = v2 ? err.read() : err.readUnsignedShort();
|
||||
byte[] dat = new byte[msgLen];
|
||||
err.read(dat);
|
||||
String errStr = new String(dat, StandardCharsets.UTF_8);
|
||||
logger.info("Server Error Code {}: {}", errorCode, errStr);
|
||||
if(errorCode == HandshakePacketTypes.SERVER_ERROR_RATELIMIT_BLOCKED) {
|
||||
if (errorCode == HandshakePacketTypes.SERVER_ERROR_RATELIMIT_BLOCKED) {
|
||||
RateLimitTracker.registerBlock(PlatformNetworking.getCurrentURI());
|
||||
mc.displayGuiScreen(GuiDisconnected.createRateLimitKick(scr));
|
||||
}else if(errorCode == HandshakePacketTypes.SERVER_ERROR_RATELIMIT_LOCKED) {
|
||||
} else if (errorCode == HandshakePacketTypes.SERVER_ERROR_RATELIMIT_LOCKED) {
|
||||
RateLimitTracker.registerLockOut(PlatformNetworking.getCurrentURI());
|
||||
mc.displayGuiScreen(GuiDisconnected.createRateLimitKick(scr));
|
||||
}else if(errorCode == HandshakePacketTypes.SERVER_ERROR_CUSTOM_MESSAGE) {
|
||||
if (IChatComponent.Serializer.jsonToComponent(errStr).getUnformattedText().toLowerCase().contains("banned from this server")) {
|
||||
} else if (errorCode == HandshakePacketTypes.SERVER_ERROR_CUSTOM_MESSAGE) {
|
||||
if (IChatComponent.Serializer.jsonToComponent(errStr).getUnformattedText().toLowerCase()
|
||||
.contains("banned from this server")) {
|
||||
EaglerProfile.updateUsernameCookies();
|
||||
reloadPage();
|
||||
}
|
||||
if (IChatComponent.Serializer.jsonToComponent(errStr).getUnformattedText().toLowerCase().contains("reload page")) {
|
||||
if (IChatComponent.Serializer.jsonToComponent(errStr).getUnformattedText().toLowerCase()
|
||||
.contains("reload page")) {
|
||||
EaglerProfile.updateUsernameCookieFromLocalStorage();
|
||||
reloadPage();
|
||||
}
|
||||
mc.displayGuiScreen(new GuiDisconnected(scr, "connect.failed", IChatComponent.Serializer.jsonToComponent(errStr)));
|
||||
}else if(connecting != null && errorCode == HandshakePacketTypes.SERVER_ERROR_AUTHENTICATION_REQUIRED) {
|
||||
mc.displayGuiScreen(
|
||||
new GuiDisconnected(scr, "connect.failed", IChatComponent.Serializer.jsonToComponent(errStr)));
|
||||
} else if (connecting != null && errorCode == HandshakePacketTypes.SERVER_ERROR_AUTHENTICATION_REQUIRED) {
|
||||
mc.displayGuiScreen(new GuiAuthenticationScreen(connecting, scr, errStr));
|
||||
}else {
|
||||
mc.displayGuiScreen(new GuiDisconnected(scr, "connect.failed", new ChatComponentText("Server Error Code " + errorCode + "\n" + errStr)));
|
||||
} else {
|
||||
mc.displayGuiScreen(new GuiDisconnected(scr, "connect.failed",
|
||||
new ChatComponentText("Server Error Code " + errorCode + "\n" + errStr)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static GuiScreen displayAuthProtocolConfirm(int protocol, GuiScreen no, GuiScreen yes) {
|
||||
if(protocol == HandshakePacketTypes.AUTH_METHOD_PLAINTEXT) {
|
||||
if (protocol == HandshakePacketTypes.AUTH_METHOD_PLAINTEXT) {
|
||||
return new GuiHandshakeApprove("plaintext", no, yes);
|
||||
}else if(protocol != HandshakePacketTypes.AUTH_METHOD_EAGLER_SHA256 && protocol != HandshakePacketTypes.AUTH_METHOD_AUTHME_SHA256) {
|
||||
} else if (protocol != HandshakePacketTypes.AUTH_METHOD_EAGLER_SHA256
|
||||
&& protocol != HandshakePacketTypes.AUTH_METHOD_AUTHME_SHA256) {
|
||||
return new GuiHandshakeApprove("unsupportedAuth", no);
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final byte[] HEX = new byte[] {
|
||||
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
|
||||
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
|
||||
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
|
||||
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,65 +21,73 @@ import net.minecraft.util.ChatComponentTranslation;
|
|||
import net.minecraft.util.IChatComponent;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EaglercraftNetworkManager {
|
||||
|
||||
|
||||
protected final String address;
|
||||
protected INetHandler nethandler = null;
|
||||
protected EnumConnectionState packetState = EnumConnectionState.HANDSHAKING;
|
||||
protected final PacketBuffer temporaryBuffer;
|
||||
protected int debugPacketCounter = 0;
|
||||
|
||||
|
||||
protected String pluginBrand = null;
|
||||
protected String pluginVersion = null;
|
||||
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("NetworkManager");
|
||||
|
||||
public EaglercraftNetworkManager(String address) {
|
||||
this.address = address;
|
||||
this.temporaryBuffer = new PacketBuffer(Unpooled.buffer(0x1FFFF));
|
||||
}
|
||||
|
||||
|
||||
public void setPluginInfo(String pluginBrand, String pluginVersion) {
|
||||
this.pluginBrand = pluginBrand;
|
||||
this.pluginVersion = pluginVersion;
|
||||
}
|
||||
|
||||
|
||||
public String getPluginBrand() {
|
||||
return pluginBrand;
|
||||
}
|
||||
|
||||
|
||||
public String getPluginVersion() {
|
||||
return pluginVersion;
|
||||
}
|
||||
|
||||
|
||||
public void connect() {
|
||||
PlatformNetworking.startPlayConnection(address);
|
||||
}
|
||||
|
||||
|
||||
public EnumEaglerConnectionState getConnectStatus() {
|
||||
return PlatformNetworking.playConnectionState();
|
||||
}
|
||||
|
||||
@JSBody(params = {}, script = "window.onbeforeunload = null; location.reload();")
|
||||
public static native void reloadPage();
|
||||
|
||||
|
||||
public void closeChannel(IChatComponent reason) {
|
||||
PlatformNetworking.playDisconnect();
|
||||
if(nethandler != null) {
|
||||
if (nethandler != null) {
|
||||
nethandler.onDisconnect(reason);
|
||||
}
|
||||
clientDisconnected = true;
|
||||
|
@ -93,20 +101,21 @@ public class EaglercraftNetworkManager {
|
|||
reloadPage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setConnectionState(EnumConnectionState state) {
|
||||
packetState = state;
|
||||
}
|
||||
|
||||
|
||||
public void processReceivedPackets() throws IOException {
|
||||
if(nethandler == null) return;
|
||||
if (nethandler == null)
|
||||
return;
|
||||
List<byte[]> pkts = PlatformNetworking.readAllPacket();
|
||||
|
||||
if(pkts == null) {
|
||||
if (pkts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0, l = pkts.size(); i < l; ++i) {
|
||||
for (int i = 0, l = pkts.size(); i < l; ++i) {
|
||||
byte[] next = pkts.get(i);
|
||||
++debugPacketCounter;
|
||||
try {
|
||||
|
@ -114,76 +123,79 @@ public class EaglercraftNetworkManager {
|
|||
nettyBuffer.writerIndex(next.length);
|
||||
PacketBuffer input = new PacketBuffer(nettyBuffer);
|
||||
int pktId = input.readVarIntFromBuffer();
|
||||
|
||||
|
||||
Packet pkt;
|
||||
try {
|
||||
pkt = packetState.getPacket(EnumPacketDirection.CLIENTBOUND, pktId);
|
||||
}catch(IllegalAccessException | InstantiationException ex) {
|
||||
} catch (IllegalAccessException | InstantiationException ex) {
|
||||
throw new IOException("Recieved a packet with type " + pktId + " which is invalid!");
|
||||
}
|
||||
|
||||
if(pkt == null) {
|
||||
throw new IOException("Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
|
||||
if (pkt == null) {
|
||||
throw new IOException(
|
||||
"Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
pkt.readPacketData(input);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new IOException("Failed to read packet type '" + pkt.getClass().getSimpleName() + "'", t);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
pkt.processPacket(nethandler);
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.", pkt.getClass().getSimpleName());
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.",
|
||||
pkt.getClass().getSimpleName());
|
||||
logger.error(t);
|
||||
}
|
||||
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process websocket frame {}! It'll be skipped for debug purposes.", debugPacketCounter);
|
||||
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process websocket frame {}! It'll be skipped for debug purposes.",
|
||||
debugPacketCounter);
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacket(Packet pkt) {
|
||||
if(!isChannelOpen()) {
|
||||
if (!isChannelOpen()) {
|
||||
logger.error("Packet was sent on a closed connection: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int i;
|
||||
try {
|
||||
i = packetState.getPacketId(EnumPacketDirection.SERVERBOUND, pkt);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Incorrect packet for state: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
temporaryBuffer.clear();
|
||||
temporaryBuffer.writeVarIntToBuffer(i);
|
||||
try {
|
||||
pkt.writePacketData(temporaryBuffer);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Failed to write packet {}!", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int len = temporaryBuffer.writerIndex();
|
||||
byte[] bytes = new byte[len];
|
||||
temporaryBuffer.getBytes(0, bytes);
|
||||
|
||||
|
||||
PlatformNetworking.writePlayPacket(bytes);
|
||||
}
|
||||
|
||||
|
||||
public void setNetHandler(INetHandler nethandler) {
|
||||
this.nethandler = nethandler;
|
||||
}
|
||||
|
||||
|
||||
public boolean isLocalChannel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean isChannelOpen() {
|
||||
return getConnectStatus() == EnumEaglerConnectionState.CONNECTED;
|
||||
}
|
||||
|
@ -197,27 +209,27 @@ public class EaglercraftNetworkManager {
|
|||
}
|
||||
|
||||
public boolean checkDisconnected() {
|
||||
if(PlatformNetworking.playConnectionState().isClosed()) {
|
||||
if (PlatformNetworking.playConnectionState().isClosed()) {
|
||||
try {
|
||||
processReceivedPackets(); // catch kick message
|
||||
} catch (IOException e) {
|
||||
}
|
||||
doClientDisconnect(new ChatComponentTranslation("disconnect.endOfStream"));
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected boolean clientDisconnected = false;
|
||||
|
||||
|
||||
protected void doClientDisconnect(IChatComponent msg) {
|
||||
if(!clientDisconnected) {
|
||||
if (!clientDisconnected) {
|
||||
clientDisconnected = true;
|
||||
if(nethandler != null) {
|
||||
if (nethandler != null) {
|
||||
this.nethandler.onDisconnect(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.socket;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -22,5 +30,5 @@ public class EncryptionNotSupportedException extends UnsupportedOperationExcepti
|
|||
"online-mode=false' in server.properties to " +
|
||||
"allow Eaglercraft connections to this server");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,16 +8,24 @@ import net.minecraft.client.gui.GuiScreen;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -49,16 +57,16 @@ public class GuiHandshakeApprove extends GuiScreen {
|
|||
bodyLines = new ArrayList();
|
||||
int i = 0;
|
||||
boolean wasNull = true;
|
||||
while(true) {
|
||||
while (true) {
|
||||
String line = getI18nOrNull("handshakeApprove." + message + ".body." + (i++));
|
||||
if(line == null) {
|
||||
if(wasNull) {
|
||||
if (line == null) {
|
||||
if (wasNull) {
|
||||
break;
|
||||
}else {
|
||||
} else {
|
||||
bodyLines.add("");
|
||||
wasNull = true;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
bodyLines.add(line);
|
||||
wasNull = false;
|
||||
}
|
||||
|
@ -66,18 +74,18 @@ public class GuiHandshakeApprove extends GuiScreen {
|
|||
int totalHeight = 10 + 10 + bodyLines.size() * 10 + 10 + 20;
|
||||
bodyY = (height - totalHeight) / 2 - 15;
|
||||
int buttonY = bodyY + totalHeight - 20;
|
||||
if(yes != null) {
|
||||
if (yes != null) {
|
||||
this.buttonList.add(new GuiButton(0, width / 2 + 3, buttonY, 100, 20, I18n.format("gui.no")));
|
||||
this.buttonList.add(new GuiButton(1, width / 2 - 103, buttonY, 100, 20, I18n.format("gui.yes")));
|
||||
}else {
|
||||
} else {
|
||||
this.buttonList.add(new GuiButton(0, width / 2 - 100, buttonY, 200, 20, I18n.format("gui.back")));
|
||||
}
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton parGuiButton) {
|
||||
if(parGuiButton.id == 0) {
|
||||
if (parGuiButton.id == 0) {
|
||||
mc.displayGuiScreen(no);
|
||||
}else if(parGuiButton.id == 1) {
|
||||
} else if (parGuiButton.id == 1) {
|
||||
mc.displayGuiScreen(yes);
|
||||
}
|
||||
}
|
||||
|
@ -85,20 +93,20 @@ public class GuiHandshakeApprove extends GuiScreen {
|
|||
public void drawScreen(int xx, int yy, float partialTicks) {
|
||||
drawBackground(0);
|
||||
drawCenteredString(fontRendererObj, titleString, width / 2, bodyY, 16777215);
|
||||
for(int i = 0, l = bodyLines.size(); i < l; ++i) {
|
||||
for (int i = 0, l = bodyLines.size(); i < l; ++i) {
|
||||
String s = bodyLines.get(i);
|
||||
if(s.length() > 0) {
|
||||
if (s.length() > 0) {
|
||||
drawCenteredString(fontRendererObj, s, width / 2, bodyY + 20 + i * 10, 16777215);
|
||||
}
|
||||
}
|
||||
super.drawScreen(xx, yy, partialTicks);
|
||||
super.drawScreen(xx, yy, partialTicks);
|
||||
}
|
||||
|
||||
private String getI18nOrNull(String key) {
|
||||
String ret = I18n.format(key);
|
||||
if(key.equals(ret)) {
|
||||
if (key.equals(ret)) {
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.socket;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -5,16 +5,24 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -47,17 +55,17 @@ public class RateLimitTracker {
|
|||
|
||||
public static void tick() {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastTickUpdate > 5000l) {
|
||||
if (millis - lastTickUpdate > 5000l) {
|
||||
lastTickUpdate = millis;
|
||||
Iterator<Long> blocksItr = blocks.values().iterator();
|
||||
while(blocksItr.hasNext()) {
|
||||
if(millis - blocksItr.next().longValue() > 900000l) {
|
||||
while (blocksItr.hasNext()) {
|
||||
if (millis - blocksItr.next().longValue() > 900000l) {
|
||||
blocksItr.remove();
|
||||
}
|
||||
}
|
||||
blocksItr = lockout.values().iterator();
|
||||
while(blocksItr.hasNext()) {
|
||||
if(millis - blocksItr.next().longValue() > 900000l) {
|
||||
while (blocksItr.hasNext()) {
|
||||
if (millis - blocksItr.next().longValue() > 900000l) {
|
||||
blocksItr.remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,24 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8.sp;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.ipc.*;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -41,56 +49,93 @@ public class IntegratedServerState {
|
|||
public static final int WORLD_FILE_MOVE = 18;
|
||||
public static final int WORLD_FILE_COPY = 19;
|
||||
public static final int WORLD_CLEAR_PLAYERS = 20;
|
||||
|
||||
|
||||
public static String getStateName(int i) {
|
||||
switch(i) {
|
||||
case WORLD_WORKER_NOT_RUNNING: return "WORLD_WORKER_NOT_RUNNING";
|
||||
case WORLD_WORKER_BOOTING: return "WORLD_WORKER_BOOTING";
|
||||
case WORLD_NONE: return "WORLD_NONE";
|
||||
case WORLD_LOADING: return "WORLD_LOADING";
|
||||
case WORLD_LOADED: return "WORLD_LOADED";
|
||||
case WORLD_UNLOADING: return "WORLD_UNLOADING";
|
||||
case WORLD_DELETING: return "WORLD_DELETING";
|
||||
case WORLD_RENAMING: return "WORLD_RENAMING";
|
||||
case WORLD_DUPLICATING: return "WORLD_DUPLICATING";
|
||||
case WORLD_PAUSED: return "WORLD_PAUSED";
|
||||
case WORLD_LISTING: return "WORLD_LISTING";
|
||||
case WORLD_SAVING: return "WORLD_SAVING";
|
||||
case WORLD_IMPORTING: return "WORLD_IMPORTING";
|
||||
case WORLD_EXPORTING: return "WORLD_EXPORTING";
|
||||
case WORLD_GET_NBT: return "WORLD_GET_NBT";
|
||||
case WORLD_LIST_FILE: return "WORLD_LIST_FILE";
|
||||
case WORLD_FILE_READ: return "WORLD_FILE_READ";
|
||||
case WORLD_FILE_WRITE: return "WORLD_FILE_WRITE";
|
||||
case WORLD_FILE_MOVE: return "WORLD_FILE_MOVE";
|
||||
case WORLD_FILE_COPY: return "WORLD_FILE_COPY";
|
||||
case WORLD_CLEAR_PLAYERS: return "WORLD_CLEAR_PLAYERS";
|
||||
default: return "INVALID";
|
||||
switch (i) {
|
||||
case WORLD_WORKER_NOT_RUNNING:
|
||||
return "WORLD_WORKER_NOT_RUNNING";
|
||||
case WORLD_WORKER_BOOTING:
|
||||
return "WORLD_WORKER_BOOTING";
|
||||
case WORLD_NONE:
|
||||
return "WORLD_NONE";
|
||||
case WORLD_LOADING:
|
||||
return "WORLD_LOADING";
|
||||
case WORLD_LOADED:
|
||||
return "WORLD_LOADED";
|
||||
case WORLD_UNLOADING:
|
||||
return "WORLD_UNLOADING";
|
||||
case WORLD_DELETING:
|
||||
return "WORLD_DELETING";
|
||||
case WORLD_RENAMING:
|
||||
return "WORLD_RENAMING";
|
||||
case WORLD_DUPLICATING:
|
||||
return "WORLD_DUPLICATING";
|
||||
case WORLD_PAUSED:
|
||||
return "WORLD_PAUSED";
|
||||
case WORLD_LISTING:
|
||||
return "WORLD_LISTING";
|
||||
case WORLD_SAVING:
|
||||
return "WORLD_SAVING";
|
||||
case WORLD_IMPORTING:
|
||||
return "WORLD_IMPORTING";
|
||||
case WORLD_EXPORTING:
|
||||
return "WORLD_EXPORTING";
|
||||
case WORLD_GET_NBT:
|
||||
return "WORLD_GET_NBT";
|
||||
case WORLD_LIST_FILE:
|
||||
return "WORLD_LIST_FILE";
|
||||
case WORLD_FILE_READ:
|
||||
return "WORLD_FILE_READ";
|
||||
case WORLD_FILE_WRITE:
|
||||
return "WORLD_FILE_WRITE";
|
||||
case WORLD_FILE_MOVE:
|
||||
return "WORLD_FILE_MOVE";
|
||||
case WORLD_FILE_COPY:
|
||||
return "WORLD_FILE_COPY";
|
||||
case WORLD_CLEAR_PLAYERS:
|
||||
return "WORLD_CLEAR_PLAYERS";
|
||||
default:
|
||||
return "INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isACKValidInState(int ack, int state) {
|
||||
switch(ack) {
|
||||
case 0xFF: return state == WORLD_WORKER_BOOTING;
|
||||
case IPCPacketFFProcessKeepAlive.EXITED: return true;
|
||||
case IPCPacketFFProcessKeepAlive.FAILURE: return true;
|
||||
case IPCPacket01StopServer.ID: return true;
|
||||
case IPCPacket00StartServer.ID: return state == WORLD_LOADING;
|
||||
case IPCPacket03DeleteWorld.ID: return state == WORLD_DELETING;
|
||||
case IPCPacket06RenameWorldNBT.ID: return (state == WORLD_DUPLICATING || state == WORLD_RENAMING);
|
||||
case IPCPacket07ImportWorld.ID: return state == WORLD_IMPORTING;
|
||||
case IPCPacket0BPause.ID:
|
||||
case IPCPacket19Autosave.ID: return (state == WORLD_SAVING || state == WORLD_PAUSED || state == WORLD_LOADED || state == WORLD_UNLOADING);
|
||||
case IPCPacket12FileWrite.ID: return state == WORLD_FILE_WRITE;
|
||||
case IPCPacket13FileCopyMove.ID: return (state == WORLD_FILE_MOVE || state == WORLD_FILE_COPY);
|
||||
case IPCPacket18ClearPlayers.ID: return state == WORLD_CLEAR_PLAYERS;
|
||||
default: return false;
|
||||
switch (ack) {
|
||||
case 0xFF:
|
||||
return state == WORLD_WORKER_BOOTING;
|
||||
case IPCPacketFFProcessKeepAlive.EXITED:
|
||||
return true;
|
||||
case IPCPacketFFProcessKeepAlive.FAILURE:
|
||||
return true;
|
||||
case IPCPacket01StopServer.ID:
|
||||
return true;
|
||||
case IPCPacket00StartServer.ID:
|
||||
return state == WORLD_LOADING;
|
||||
case IPCPacket03DeleteWorld.ID:
|
||||
return state == WORLD_DELETING;
|
||||
case IPCPacket06RenameWorldNBT.ID:
|
||||
return (state == WORLD_DUPLICATING || state == WORLD_RENAMING);
|
||||
case IPCPacket07ImportWorld.ID:
|
||||
return state == WORLD_IMPORTING;
|
||||
case IPCPacket0BPause.ID:
|
||||
case IPCPacket19Autosave.ID:
|
||||
return (state == WORLD_SAVING || state == WORLD_PAUSED || state == WORLD_LOADED
|
||||
|| state == WORLD_UNLOADING);
|
||||
case IPCPacket12FileWrite.ID:
|
||||
return state == WORLD_FILE_WRITE;
|
||||
case IPCPacket13FileCopyMove.ID:
|
||||
return (state == WORLD_FILE_MOVE || state == WORLD_FILE_COPY);
|
||||
case IPCPacket18ClearPlayers.ID:
|
||||
return state == WORLD_CLEAR_PLAYERS;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void assertState(int ack, int state) {
|
||||
if(!isACKValidInState(ack, state)) {
|
||||
String msg = "Recieved ACK " + ack + " while the client state was " + state + " '" + getStateName(state) + "'";
|
||||
if (!isACKValidInState(ack, state)) {
|
||||
String msg = "Recieved ACK " + ack + " while the client state was " + state + " '" + getStateName(state)
|
||||
+ "'";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,16 +33,24 @@ import net.minecraft.world.storage.SaveFormatComparator;
|
|||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -67,14 +75,15 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
private static boolean isPaused = false;
|
||||
private static List<String> integratedServerTPS = new ArrayList();
|
||||
private static long integratedServerLastTPSUpdate = 0;
|
||||
public static final ClientIntegratedServerNetworkManager localPlayerNetworkManager = new ClientIntegratedServerNetworkManager(PLAYER_CHANNEL);
|
||||
public static final ClientIntegratedServerNetworkManager localPlayerNetworkManager = new ClientIntegratedServerNetworkManager(
|
||||
PLAYER_CHANNEL);
|
||||
private static final List<String> openLANChannels = new ArrayList();
|
||||
|
||||
private SingleplayerServerController() {
|
||||
}
|
||||
|
||||
public static void startIntegratedServerWorker() {
|
||||
if(statusState == IntegratedServerState.WORLD_WORKER_NOT_RUNNING) {
|
||||
if (statusState == IntegratedServerState.WORLD_WORKER_NOT_RUNNING) {
|
||||
exceptions.clear();
|
||||
statusState = IntegratedServerState.WORLD_WORKER_BOOTING;
|
||||
loggingState = true;
|
||||
|
@ -83,7 +92,8 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
}
|
||||
|
||||
public static boolean isIntegratedServerWorkerStarted() {
|
||||
return statusState != IntegratedServerState.WORLD_WORKER_NOT_RUNNING && statusState != IntegratedServerState.WORLD_WORKER_BOOTING;
|
||||
return statusState != IntegratedServerState.WORLD_WORKER_NOT_RUNNING
|
||||
&& statusState != IntegratedServerState.WORLD_WORKER_BOOTING;
|
||||
}
|
||||
|
||||
public static boolean isIntegratedServerWorkerAlive() {
|
||||
|
@ -99,81 +109,85 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
}
|
||||
|
||||
public static boolean isWorldNotLoaded() {
|
||||
return statusState == IntegratedServerState.WORLD_NONE || statusState == IntegratedServerState.WORLD_WORKER_NOT_RUNNING ||
|
||||
return statusState == IntegratedServerState.WORLD_NONE
|
||||
|| statusState == IntegratedServerState.WORLD_WORKER_NOT_RUNNING ||
|
||||
statusState == IntegratedServerState.WORLD_WORKER_BOOTING;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isWorldRunning() {
|
||||
return statusState == IntegratedServerState.WORLD_LOADED || statusState == IntegratedServerState.WORLD_PAUSED ||
|
||||
statusState == IntegratedServerState.WORLD_LOADING || statusState == IntegratedServerState.WORLD_SAVING;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isWorldReady() {
|
||||
return statusState == IntegratedServerState.WORLD_LOADED || statusState == IntegratedServerState.WORLD_PAUSED ||
|
||||
statusState == IntegratedServerState.WORLD_SAVING;
|
||||
}
|
||||
|
||||
|
||||
public static int getStatusState() {
|
||||
return statusState;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isChannelOpen(String ch) {
|
||||
return openLANChannels.contains(ch);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isChannelNameAllowed(String ch) {
|
||||
return !IPC_CHANNEL.equals(ch) && !PLAYER_CHANNEL.equals(ch);
|
||||
}
|
||||
|
||||
|
||||
public static void openPlayerChannel(String ch) {
|
||||
if(openLANChannels.contains(ch)) {
|
||||
if (openLANChannels.contains(ch)) {
|
||||
logger.error("Tried to open channel that already exists: \"{}\"", ch);
|
||||
} else if (!isChannelNameAllowed(ch)) {
|
||||
logger.error("Tried to open disallowed channel name: \"{}\"", ch);
|
||||
}else {
|
||||
} else {
|
||||
openLANChannels.add(ch);
|
||||
sendIPCPacket(new IPCPacket0CPlayerChannel(ch, true));
|
||||
PlatformWebRTC.serverLANCreatePeer(ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void closePlayerChannel(String ch) {
|
||||
if(!openLANChannels.remove(ch)) {
|
||||
if (!openLANChannels.remove(ch)) {
|
||||
logger.error("Tried to close channel that doesn't exist: \"{}\"", ch);
|
||||
}else {
|
||||
} else {
|
||||
sendIPCPacket(new IPCPacket0CPlayerChannel(ch, false));
|
||||
PlatformWebRTC.serverLANDisconnectPeer(ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void openLocalPlayerChannel() {
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = true;
|
||||
sendIPCPacket(new IPCPacket0CPlayerChannel(PLAYER_CHANNEL, true));
|
||||
}
|
||||
|
||||
|
||||
public static void closeLocalPlayerChannel() {
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
sendIPCPacket(new IPCPacket0CPlayerChannel(PLAYER_CHANNEL, false));
|
||||
}
|
||||
|
||||
|
||||
private static void ensureReady() {
|
||||
if(!isReady()) {
|
||||
String msg = "Server is in state " + statusState + " '" + IntegratedServerState.getStateName(statusState) + "' which is not the 'WORLD_NONE' state for the requested IPC operation";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureWorldReady() {
|
||||
if(!isWorldReady()) {
|
||||
String msg = "Server is in state " + statusState + " '" + IntegratedServerState.getStateName(statusState) + "' which is not the 'WORLD_LOADED' state for the requested IPC operation";
|
||||
if (!isReady()) {
|
||||
String msg = "Server is in state " + statusState + " '" + IntegratedServerState.getStateName(statusState)
|
||||
+ "' which is not the 'WORLD_NONE' state for the requested IPC operation";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void launchEaglercraftServer(String folderName, int difficulty, int viewDistance, WorldSettings settings) {
|
||||
private static void ensureWorldReady() {
|
||||
if (!isWorldReady()) {
|
||||
String msg = "Server is in state " + statusState + " '" + IntegratedServerState.getStateName(statusState)
|
||||
+ "' which is not the 'WORLD_LOADED' state for the requested IPC operation";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void launchEaglercraftServer(String folderName, int difficulty, int viewDistance,
|
||||
WorldSettings settings) {
|
||||
ensureReady();
|
||||
clearTPS();
|
||||
if(settings != null) {
|
||||
if (settings != null) {
|
||||
sendIPCPacket(new IPCPacket02InitWorld(folderName, settings.getGameType().getID(),
|
||||
settings.getTerrainType().getWorldTypeID(), settings.getWorldName(), settings.getSeed(),
|
||||
settings.areCommandsAllowed(), settings.isMapFeaturesEnabled(), settings.isBonusChestEnabled(),
|
||||
|
@ -181,10 +195,11 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
}
|
||||
statusState = IntegratedServerState.WORLD_LOADING;
|
||||
worldStatusProgress = 0.0f;
|
||||
sendIPCPacket(new IPCPacket00StartServer(folderName, EaglerProfile.getName(), difficulty, viewDistance, EagRuntime.getConfiguration().isDemo()));
|
||||
sendIPCPacket(new IPCPacket00StartServer(folderName, EaglerProfile.getName(), difficulty, viewDistance,
|
||||
EagRuntime.getConfiguration().isDemo()));
|
||||
}
|
||||
|
||||
public static void clearTPS() {
|
||||
public static void clearTPS() {
|
||||
integratedServerTPS.clear();
|
||||
integratedServerLastTPSUpdate = 0l;
|
||||
}
|
||||
|
@ -199,40 +214,41 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
|
||||
public static boolean hangupEaglercraftServer() {
|
||||
LANServerController.closeLAN();
|
||||
if(isWorldRunning()) {
|
||||
if (isWorldRunning()) {
|
||||
logger.error("Shutting down integrated server due to unexpected client hangup, this is a memleak");
|
||||
statusState = IntegratedServerState.WORLD_UNLOADING;
|
||||
sendIPCPacket(new IPCPacket01StopServer());
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shutdownEaglercraftServer() {
|
||||
LANServerController.closeLAN();
|
||||
if(isWorldRunning()) {
|
||||
if (isWorldRunning()) {
|
||||
logger.info("Shutting down integrated server");
|
||||
statusState = IntegratedServerState.WORLD_UNLOADING;
|
||||
sendIPCPacket(new IPCPacket01StopServer());
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void autoSave() {
|
||||
if(!isPaused) {
|
||||
if (!isPaused) {
|
||||
statusState = IntegratedServerState.WORLD_SAVING;
|
||||
sendIPCPacket(new IPCPacket19Autosave());
|
||||
}
|
||||
}
|
||||
|
||||
public static void setPaused(boolean pause) {
|
||||
if(statusState != IntegratedServerState.WORLD_LOADED && statusState != IntegratedServerState.WORLD_PAUSED && statusState != IntegratedServerState.WORLD_SAVING) {
|
||||
if (statusState != IntegratedServerState.WORLD_LOADED && statusState != IntegratedServerState.WORLD_PAUSED
|
||||
&& statusState != IntegratedServerState.WORLD_SAVING) {
|
||||
return;
|
||||
}
|
||||
if(isPaused != pause) {
|
||||
if (isPaused != pause) {
|
||||
sendIPCPacket(new IPCPacket0BPause(pause));
|
||||
isPaused = pause;
|
||||
}
|
||||
|
@ -240,32 +256,33 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
|
||||
public static void runTick() {
|
||||
List<IPCPacketData> pktList = ClientPlatformSingleplayer.recieveAllPacket();
|
||||
if(pktList != null) {
|
||||
if (pktList != null) {
|
||||
IPCPacketData packetData;
|
||||
for(int i = 0, l = pktList.size(); i < l; ++i) {
|
||||
for (int i = 0, l = pktList.size(); i < l; ++i) {
|
||||
packetData = pktList.get(i);
|
||||
if(packetData.channel.equals(SingleplayerServerController.IPC_CHANNEL)) {
|
||||
if (packetData.channel.equals(SingleplayerServerController.IPC_CHANNEL)) {
|
||||
IPCPacketBase ipc;
|
||||
try {
|
||||
ipc = IPCPacketManager.IPCDeserialize(packetData.contents);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to deserialize IPC packet", ex);
|
||||
}
|
||||
handleIPCPacket(ipc);
|
||||
}else if(packetData.channel.equals(SingleplayerServerController.PLAYER_CHANNEL)) {
|
||||
if(localPlayerNetworkManager.getConnectStatus() != EnumEaglerConnectionState.CLOSED) {
|
||||
} else if (packetData.channel.equals(SingleplayerServerController.PLAYER_CHANNEL)) {
|
||||
if (localPlayerNetworkManager.getConnectStatus() != EnumEaglerConnectionState.CLOSED) {
|
||||
localPlayerNetworkManager.addRecievedPacket(packetData.contents);
|
||||
}else {
|
||||
logger.warn("Recieved {} byte packet on closed local player connection", packetData.contents.length);
|
||||
} else {
|
||||
logger.warn("Recieved {} byte packet on closed local player connection",
|
||||
packetData.contents.length);
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
PlatformWebRTC.serverLANWritePacket(packetData.channel, packetData.contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean logWindowState = PlatformApplication.isShowingDebugConsole();
|
||||
if(loggingState != logWindowState) {
|
||||
if (loggingState != logWindowState) {
|
||||
loggingState = logWindowState;
|
||||
sendIPCPacket(new IPCPacket21EnableLogging(logWindowState));
|
||||
}
|
||||
|
@ -274,128 +291,135 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
}
|
||||
|
||||
private static void handleIPCPacket(IPCPacketBase ipc) {
|
||||
switch(ipc.id()) {
|
||||
case IPCPacketFFProcessKeepAlive.ID: {
|
||||
IPCPacketFFProcessKeepAlive pkt = (IPCPacketFFProcessKeepAlive)ipc;
|
||||
IntegratedServerState.assertState(pkt.ack, statusState);
|
||||
switch(pkt.ack) {
|
||||
case 0xFF:
|
||||
logger.info("Integrated server signaled a successful boot");
|
||||
sendIPCPacket(new IPCPacket14StringList(IPCPacket14StringList.LOCALE, StringTranslate.dump()));
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacket00StartServer.ID:
|
||||
statusState = IntegratedServerState.WORLD_LOADED;
|
||||
isPaused = false;
|
||||
break;
|
||||
case IPCPacket0BPause.ID:
|
||||
case IPCPacket19Autosave.ID:
|
||||
if(statusState != IntegratedServerState.WORLD_UNLOADING) {
|
||||
statusState = isPaused ? IntegratedServerState.WORLD_PAUSED : IntegratedServerState.WORLD_LOADED;
|
||||
}
|
||||
break;
|
||||
case IPCPacketFFProcessKeepAlive.FAILURE:
|
||||
logger.error("Server signaled 'FAILURE' response in state '{}'", IntegratedServerState.getStateName(statusState));
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
callFailed = true;
|
||||
break;
|
||||
case IPCPacket01StopServer.ID:
|
||||
LANServerController.closeLAN();
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacket06RenameWorldNBT.ID:
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacket03DeleteWorld.ID:
|
||||
case IPCPacket07ImportWorld.ID:
|
||||
case IPCPacket12FileWrite.ID:
|
||||
case IPCPacket13FileCopyMove.ID:
|
||||
case IPCPacket18ClearPlayers.ID:
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacketFFProcessKeepAlive.EXITED:
|
||||
logger.error("Server signaled 'EXITED' response in state '{}'", IntegratedServerState.getStateName(statusState));
|
||||
if(ClientPlatformSingleplayer.canKillWorker()) {
|
||||
ClientPlatformSingleplayer.killWorker();
|
||||
}
|
||||
LANServerController.closeLAN();
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
statusState = IntegratedServerState.WORLD_WORKER_NOT_RUNNING;
|
||||
callFailed = true;
|
||||
break;
|
||||
default:
|
||||
logger.error("IPC acknowledge packet type 0x{} was not handled", Integer.toHexString(pkt.ack));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket09RequestResponse.ID: {
|
||||
IPCPacket09RequestResponse pkt = (IPCPacket09RequestResponse)ipc;
|
||||
if(statusState == IntegratedServerState.WORLD_EXPORTING) {
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
exportResponse = pkt.response;
|
||||
}else {
|
||||
logger.error("IPCPacket09RequestResponse was recieved but statusState was '{}' instead of 'WORLD_EXPORTING'", IntegratedServerState.getStateName(statusState));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0DProgressUpdate.ID: {
|
||||
IPCPacket0DProgressUpdate pkt = (IPCPacket0DProgressUpdate)ipc;
|
||||
worldStatusString = pkt.updateMessage;
|
||||
worldStatusProgress = pkt.updateProgress;
|
||||
break;
|
||||
}
|
||||
case IPCPacket15Crashed.ID: {
|
||||
exceptions.add((IPCPacket15Crashed)ipc);
|
||||
if(exceptions.size() > 64) {
|
||||
exceptions.remove(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket16NBTList.ID: {
|
||||
IPCPacket16NBTList pkt = (IPCPacket16NBTList)ipc;
|
||||
if(pkt.opCode == IPCPacket16NBTList.WORLD_LIST && statusState == IntegratedServerState.WORLD_LISTING) {
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
saveListNBT.clear();
|
||||
saveListNBT.addAll(pkt.nbtTagList);
|
||||
loadSaveComparators();
|
||||
}else {
|
||||
logger.error("IPC packet type 0x{} class '{}' contained invalid opCode {} in state {} '{}'", Integer.toHexString(ipc.id()), ipc.getClass().getSimpleName(), pkt.opCode, statusState, IntegratedServerState.getStateName(statusState));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0CPlayerChannel.ID: {
|
||||
IPCPacket0CPlayerChannel pkt = (IPCPacket0CPlayerChannel)ipc;
|
||||
if(!pkt.open) {
|
||||
if(pkt.channel.equals(PLAYER_CHANNEL)) {
|
||||
LANServerController.closeLAN();
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
logger.error("Local player channel was closed");
|
||||
}else {
|
||||
PlatformWebRTC.serverLANDisconnectPeer(pkt.channel);
|
||||
switch (ipc.id()) {
|
||||
case IPCPacketFFProcessKeepAlive.ID: {
|
||||
IPCPacketFFProcessKeepAlive pkt = (IPCPacketFFProcessKeepAlive) ipc;
|
||||
IntegratedServerState.assertState(pkt.ack, statusState);
|
||||
switch (pkt.ack) {
|
||||
case 0xFF:
|
||||
logger.info("Integrated server signaled a successful boot");
|
||||
sendIPCPacket(new IPCPacket14StringList(IPCPacket14StringList.LOCALE, StringTranslate.dump()));
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacket00StartServer.ID:
|
||||
statusState = IntegratedServerState.WORLD_LOADED;
|
||||
isPaused = false;
|
||||
break;
|
||||
case IPCPacket0BPause.ID:
|
||||
case IPCPacket19Autosave.ID:
|
||||
if (statusState != IntegratedServerState.WORLD_UNLOADING) {
|
||||
statusState = isPaused ? IntegratedServerState.WORLD_PAUSED
|
||||
: IntegratedServerState.WORLD_LOADED;
|
||||
}
|
||||
break;
|
||||
case IPCPacketFFProcessKeepAlive.FAILURE:
|
||||
logger.error("Server signaled 'FAILURE' response in state '{}'",
|
||||
IntegratedServerState.getStateName(statusState));
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
callFailed = true;
|
||||
break;
|
||||
case IPCPacket01StopServer.ID:
|
||||
LANServerController.closeLAN();
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacket06RenameWorldNBT.ID:
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacket03DeleteWorld.ID:
|
||||
case IPCPacket07ImportWorld.ID:
|
||||
case IPCPacket12FileWrite.ID:
|
||||
case IPCPacket13FileCopyMove.ID:
|
||||
case IPCPacket18ClearPlayers.ID:
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
break;
|
||||
case IPCPacketFFProcessKeepAlive.EXITED:
|
||||
logger.error("Server signaled 'EXITED' response in state '{}'",
|
||||
IntegratedServerState.getStateName(statusState));
|
||||
if (ClientPlatformSingleplayer.canKillWorker()) {
|
||||
ClientPlatformSingleplayer.killWorker();
|
||||
}
|
||||
LANServerController.closeLAN();
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
statusState = IntegratedServerState.WORLD_WORKER_NOT_RUNNING;
|
||||
callFailed = true;
|
||||
break;
|
||||
default:
|
||||
logger.error("IPC acknowledge packet type 0x{} was not handled", Integer.toHexString(pkt.ack));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket14StringList.ID: {
|
||||
IPCPacket14StringList pkt = (IPCPacket14StringList)ipc;
|
||||
if(pkt.opCode == IPCPacket14StringList.SERVER_TPS) {
|
||||
integratedServerTPS.clear();
|
||||
integratedServerTPS.addAll(pkt.stringList);
|
||||
integratedServerLastTPSUpdate = System.currentTimeMillis();
|
||||
}else {
|
||||
logger.warn("Strange string list type {} recieved!", pkt.opCode);
|
||||
case IPCPacket09RequestResponse.ID: {
|
||||
IPCPacket09RequestResponse pkt = (IPCPacket09RequestResponse) ipc;
|
||||
if (statusState == IntegratedServerState.WORLD_EXPORTING) {
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
exportResponse = pkt.response;
|
||||
} else {
|
||||
logger.error(
|
||||
"IPCPacket09RequestResponse was recieved but statusState was '{}' instead of 'WORLD_EXPORTING'",
|
||||
IntegratedServerState.getStateName(statusState));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket20LoggerMessage.ID: {
|
||||
IPCPacket20LoggerMessage pkt = (IPCPacket20LoggerMessage)ipc;
|
||||
PlatformApplication.addLogMessage(pkt.logMessage, pkt.isError);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Unexpected IPC packet type recieved on client: " + ipc.id());
|
||||
case IPCPacket0DProgressUpdate.ID: {
|
||||
IPCPacket0DProgressUpdate pkt = (IPCPacket0DProgressUpdate) ipc;
|
||||
worldStatusString = pkt.updateMessage;
|
||||
worldStatusProgress = pkt.updateProgress;
|
||||
break;
|
||||
}
|
||||
case IPCPacket15Crashed.ID: {
|
||||
exceptions.add((IPCPacket15Crashed) ipc);
|
||||
if (exceptions.size() > 64) {
|
||||
exceptions.remove(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket16NBTList.ID: {
|
||||
IPCPacket16NBTList pkt = (IPCPacket16NBTList) ipc;
|
||||
if (pkt.opCode == IPCPacket16NBTList.WORLD_LIST && statusState == IntegratedServerState.WORLD_LISTING) {
|
||||
statusState = IntegratedServerState.WORLD_NONE;
|
||||
saveListNBT.clear();
|
||||
saveListNBT.addAll(pkt.nbtTagList);
|
||||
loadSaveComparators();
|
||||
} else {
|
||||
logger.error("IPC packet type 0x{} class '{}' contained invalid opCode {} in state {} '{}'",
|
||||
Integer.toHexString(ipc.id()), ipc.getClass().getSimpleName(), pkt.opCode, statusState,
|
||||
IntegratedServerState.getStateName(statusState));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0CPlayerChannel.ID: {
|
||||
IPCPacket0CPlayerChannel pkt = (IPCPacket0CPlayerChannel) ipc;
|
||||
if (!pkt.open) {
|
||||
if (pkt.channel.equals(PLAYER_CHANNEL)) {
|
||||
LANServerController.closeLAN();
|
||||
localPlayerNetworkManager.isPlayerChannelOpen = false;
|
||||
logger.error("Local player channel was closed");
|
||||
} else {
|
||||
PlatformWebRTC.serverLANDisconnectPeer(pkt.channel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket14StringList.ID: {
|
||||
IPCPacket14StringList pkt = (IPCPacket14StringList) ipc;
|
||||
if (pkt.opCode == IPCPacket14StringList.SERVER_TPS) {
|
||||
integratedServerTPS.clear();
|
||||
integratedServerTPS.addAll(pkt.stringList);
|
||||
integratedServerLastTPSUpdate = System.currentTimeMillis();
|
||||
} else {
|
||||
logger.warn("Strange string list type {} recieved!", pkt.opCode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket20LoggerMessage.ID: {
|
||||
IPCPacket20LoggerMessage pkt = (IPCPacket20LoggerMessage) ipc;
|
||||
PlatformApplication.addLogMessage(pkt.logMessage, pkt.isError);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Unexpected IPC packet type recieved on client: " + ipc.id());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,15 +427,14 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
byte[] pkt;
|
||||
try {
|
||||
pkt = IPCPacketManager.IPCSerialize(ipc);
|
||||
}catch (IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to serialize IPC packet", ex);
|
||||
}
|
||||
ClientPlatformSingleplayer.sendPacket(new IPCPacketData(IPC_CHANNEL, pkt));
|
||||
}
|
||||
|
||||
|
||||
private static boolean callFailed = false;
|
||||
|
||||
|
||||
public static boolean didLastCallFail() {
|
||||
boolean c = callFailed;
|
||||
callFailed = false;
|
||||
|
@ -421,18 +444,18 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
public static void importWorld(String name, byte[] data, int format, byte gameRules) {
|
||||
ensureReady();
|
||||
statusState = IntegratedServerState.WORLD_IMPORTING;
|
||||
sendIPCPacket(new IPCPacket07ImportWorld(name, data, (byte)format, gameRules));
|
||||
sendIPCPacket(new IPCPacket07ImportWorld(name, data, (byte) format, gameRules));
|
||||
}
|
||||
|
||||
|
||||
public static void exportWorld(String name, int format) {
|
||||
ensureReady();
|
||||
statusState = IntegratedServerState.WORLD_EXPORTING;
|
||||
if(format == IPCPacket05RequestData.REQUEST_LEVEL_EAG) {
|
||||
name = name + (new String(new char[] { (char)253, (char)233, (char)233 })) + EaglerProfile.getName();
|
||||
if (format == IPCPacket05RequestData.REQUEST_LEVEL_EAG) {
|
||||
name = name + (new String(new char[] { (char) 253, (char) 233, (char) 233 })) + EaglerProfile.getName();
|
||||
}
|
||||
sendIPCPacket(new IPCPacket05RequestData(name, (byte)format));
|
||||
sendIPCPacket(new IPCPacket05RequestData(name, (byte) format));
|
||||
}
|
||||
|
||||
|
||||
private static byte[] exportResponse = null;
|
||||
|
||||
public static byte[] getExportResponse() {
|
||||
|
@ -440,11 +463,11 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
exportResponse = null;
|
||||
return dat;
|
||||
}
|
||||
|
||||
|
||||
public static String worldStatusString() {
|
||||
return worldStatusString;
|
||||
}
|
||||
|
||||
|
||||
public static float worldStatusProgress() {
|
||||
return worldStatusProgress;
|
||||
}
|
||||
|
@ -455,7 +478,7 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
|
||||
public static IPCPacket15Crashed[] worldStatusErrors() {
|
||||
int l = exceptions.size();
|
||||
if(l == 0) {
|
||||
if (l == 0) {
|
||||
return null;
|
||||
}
|
||||
IPCPacket15Crashed[] pkts = exceptions.toArray(new IPCPacket15Crashed[l]);
|
||||
|
@ -472,10 +495,10 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
private static void loadSaveComparators() {
|
||||
saveListMap.clear();
|
||||
saveListCache.clear();
|
||||
for(int j = 0, l = saveListNBT.size(); j < l; ++j) {
|
||||
for (int j = 0, l = saveListNBT.size(); j < l; ++j) {
|
||||
NBTTagCompound nbt = saveListNBT.get(j);
|
||||
String folderName = nbt.getString("folderNameEagler");
|
||||
if(!StringUtils.isEmpty(folderName)) {
|
||||
if (!StringUtils.isEmpty(folderName)) {
|
||||
WorldInfo worldinfo = new WorldInfo(nbt.getCompoundTag("Data"));
|
||||
saveListMap.put(folderName, worldinfo);
|
||||
String s1 = worldinfo.getWorldName();
|
||||
|
@ -572,19 +595,20 @@ public class SingleplayerServerController implements ISaveFormat {
|
|||
}
|
||||
|
||||
public static void updateLocale(List<String> dump) {
|
||||
if(statusState != IntegratedServerState.WORLD_WORKER_NOT_RUNNING) {
|
||||
if (statusState != IntegratedServerState.WORLD_WORKER_NOT_RUNNING) {
|
||||
sendIPCPacket(new IPCPacket14StringList(IPCPacket14StringList.LOCALE, dump));
|
||||
}
|
||||
}
|
||||
|
||||
public static void setDifficulty(int difficultyId) {
|
||||
if(isWorldRunning()) {
|
||||
sendIPCPacket(new IPCPacket0ASetWorldDifficulty((byte)difficultyId));
|
||||
if (isWorldRunning()) {
|
||||
sendIPCPacket(new IPCPacket0ASetWorldDifficulty((byte) difficultyId));
|
||||
}
|
||||
}
|
||||
|
||||
public static void configureLAN(net.minecraft.world.WorldSettings.GameType enumGameType, boolean allowCommands) {
|
||||
sendIPCPacket(new IPCPacket17ConfigureLAN(enumGameType.getID(), allowCommands, LANServerController.currentICEServers));
|
||||
sendIPCPacket(new IPCPacket17ConfigureLAN(enumGameType.getID(), allowCommands,
|
||||
LANServerController.currentICEServers));
|
||||
}
|
||||
|
||||
public static boolean isClientInEaglerSingleplayerOrLAN() {
|
||||
|
|
|
@ -13,16 +13,24 @@ import net.minecraft.util.EnumChatFormatting;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -46,7 +54,7 @@ public class GuiNetworkSettingsButton extends Gui {
|
|||
|
||||
int w = mc.fontRendererObj.getStringWidth(text);
|
||||
boolean hover = xx > 1 && yy > 1 && xx < (w * 3 / 4) + 7 && yy < 12;
|
||||
if(hover) {
|
||||
if (hover) {
|
||||
Mouse.showCursor(EnumCursorType.HAND);
|
||||
}
|
||||
|
||||
|
@ -57,13 +65,14 @@ public class GuiNetworkSettingsButton extends Gui {
|
|||
|
||||
public void mouseClicked(int xx, int yy, int btn) {
|
||||
int w = mc.fontRendererObj.getStringWidth(text);
|
||||
if(xx > 2 && yy > 2 && xx < (w * 3 / 4) + 5 && yy < 12) {
|
||||
if(LANServerController.supported()) {
|
||||
if (xx > 2 && yy > 2 && xx < (w * 3 / 4) + 5 && yy < 12) {
|
||||
if (LANServerController.supported()) {
|
||||
mc.displayGuiScreen(GuiScreenLANInfo.showLANInfoScreen(new GuiScreenRelay(screen)));
|
||||
}else {
|
||||
} else {
|
||||
mc.displayGuiScreen(new GuiScreenLANNotSupported(screen));
|
||||
}
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,16 +9,24 @@ import net.minecraft.client.gui.GuiTextField;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -52,14 +60,18 @@ public class GuiScreenAddRelay extends GuiScreen {
|
|||
this.parentGui.addNewAddr = "";
|
||||
this.parentGui.addNewPrimary = RelayManager.relayManager.count() == 0;
|
||||
int sslOff = EagRuntime.requireSSL() ? 36 : 0;
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12 + sslOff, I18n.format("addRelay.add")));
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12 + sslOff, I18n.format("gui.cancel")));
|
||||
this.buttonList.add(new GuiButton(2, this.width / 2 - 100, 142, I18n.format("addRelay.primary") + ": " + (this.parentGui.addNewPrimary ? I18n.format("gui.yes") : I18n.format("gui.no"))));
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12 + sslOff,
|
||||
I18n.format("addRelay.add")));
|
||||
this.buttonList.add(
|
||||
new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12 + sslOff, I18n.format("gui.cancel")));
|
||||
this.buttonList.add(new GuiButton(2, this.width / 2 - 100, 142, I18n.format("addRelay.primary") + ": "
|
||||
+ (this.parentGui.addNewPrimary ? I18n.format("gui.yes") : I18n.format("gui.no"))));
|
||||
this.serverName = new GuiTextField(3, this.fontRendererObj, this.width / 2 - 100, 106, 200, 20);
|
||||
this.serverAddress = new GuiTextField(4, this.fontRendererObj, this.width / 2 - 100, 66, 200, 20);
|
||||
this.serverAddress.setMaxStringLength(128);
|
||||
this.serverAddress.setFocused(true);
|
||||
((GuiButton) this.buttonList.get(0)).enabled = this.serverAddress.getText().length() > 0 && this.serverAddress.getText().split(":").length > 0 && this.serverName.getText().length() > 0;
|
||||
((GuiButton) this.buttonList.get(0)).enabled = this.serverAddress.getText().length() > 0
|
||||
&& this.serverAddress.getText().split(":").length > 0 && this.serverName.getText().length() > 0;
|
||||
this.serverName.setText(this.parentGui.addNewName);
|
||||
}
|
||||
|
||||
|
@ -84,7 +96,8 @@ public class GuiScreenAddRelay extends GuiScreen {
|
|||
this.parentGui.confirmClicked(true, 0);
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
this.parentGui.addNewPrimary = !this.parentGui.addNewPrimary;
|
||||
((GuiButton) this.buttonList.get(2)).displayString = I18n.format("addRelay.primary") + ": " + (this.parentGui.addNewPrimary ? I18n.format("gui.yes") : I18n.format("gui.no"));
|
||||
((GuiButton) this.buttonList.get(2)).displayString = I18n.format("addRelay.primary") + ": "
|
||||
+ (this.parentGui.addNewPrimary ? I18n.format("gui.yes") : I18n.format("gui.no"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +124,8 @@ public class GuiScreenAddRelay extends GuiScreen {
|
|||
this.actionPerformed((GuiButton) this.buttonList.get(0));
|
||||
}
|
||||
|
||||
((GuiButton) this.buttonList.get(0)).enabled = this.serverAddress.getText().length() > 0 && this.serverAddress.getText().split(":").length > 0 && this.serverName.getText().length() > 0;
|
||||
((GuiButton) this.buttonList.get(0)).enabled = this.serverAddress.getText().length() > 0
|
||||
&& this.serverAddress.getText().split(":").length > 0 && this.serverName.getText().length() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,9 +145,11 @@ public class GuiScreenAddRelay extends GuiScreen {
|
|||
this.drawCenteredString(this.fontRendererObj, I18n.format("addRelay.title"), this.width / 2, 17, 16777215);
|
||||
this.drawString(this.fontRendererObj, I18n.format("addRelay.address"), this.width / 2 - 100, 53, 10526880);
|
||||
this.drawString(this.fontRendererObj, I18n.format("addRelay.name"), this.width / 2 - 100, 94, 10526880);
|
||||
if(EagRuntime.requireSSL()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("addServer.SSLWarn1"), this.width / 2, 169, 0xccccff);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("addServer.SSLWarn2"), this.width / 2, 181, 0xccccff);
|
||||
if (EagRuntime.requireSSL()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("addServer.SSLWarn1"), this.width / 2, 169,
|
||||
0xccccff);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("addServer.SSLWarn2"), this.width / 2, 181,
|
||||
0xccccff);
|
||||
}
|
||||
this.serverName.drawTextBox();
|
||||
this.serverAddress.drawTextBox();
|
||||
|
|
|
@ -14,16 +14,24 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -39,87 +47,103 @@ public class GuiScreenBackupWorldSelection extends GuiScreen {
|
|||
private GuiButton worldBackup = null;
|
||||
private long worldSeed;
|
||||
private NBTTagCompound levelDat;
|
||||
|
||||
|
||||
private String worldName;
|
||||
|
||||
|
||||
public GuiScreenBackupWorldSelection(GuiScreen selectWorld, String worldName, NBTTagCompound levelDat) {
|
||||
this.selectWorld = selectWorld;
|
||||
this.worldName = worldName;
|
||||
this.levelDat = levelDat;
|
||||
this.worldSeed = levelDat.getCompoundTag("Data").getLong("RandomSeed");
|
||||
}
|
||||
|
||||
|
||||
public void initGui() {
|
||||
this.buttonList.add(worldRecreate = new GuiButton(1, this.width / 2 - 100, this.height / 5 + 5, I18n.format("singleplayer.backup.recreate")));
|
||||
this.buttonList.add(worldDuplicate = new GuiButton(2, this.width / 2 - 100, this.height / 5 + 30, I18n.format("singleplayer.backup.duplicate")));
|
||||
this.buttonList.add(worldExport = new GuiButton(3, this.width / 2 - 100, this.height / 5 + 80, I18n.format("singleplayer.backup.export")));
|
||||
this.buttonList.add(worldConvert = new GuiButton(4, this.width / 2 - 100, this.height / 5 + 105, I18n.format("singleplayer.backup.vanilla")));
|
||||
this.buttonList.add(worldBackup = new GuiButton(5, this.width / 2 - 100, this.height / 5 + 136, I18n.format("singleplayer.backup.clearPlayerData")));
|
||||
this.buttonList.add(worldRecreate = new GuiButton(1, this.width / 2 - 100, this.height / 5 + 5,
|
||||
I18n.format("singleplayer.backup.recreate")));
|
||||
this.buttonList.add(worldDuplicate = new GuiButton(2, this.width / 2 - 100, this.height / 5 + 30,
|
||||
I18n.format("singleplayer.backup.duplicate")));
|
||||
this.buttonList.add(worldExport = new GuiButton(3, this.width / 2 - 100, this.height / 5 + 80,
|
||||
I18n.format("singleplayer.backup.export")));
|
||||
this.buttonList.add(worldConvert = new GuiButton(4, this.width / 2 - 100, this.height / 5 + 105,
|
||||
I18n.format("singleplayer.backup.vanilla")));
|
||||
this.buttonList.add(worldBackup = new GuiButton(5, this.width / 2 - 100, this.height / 5 + 136,
|
||||
I18n.format("singleplayer.backup.clearPlayerData")));
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 155, I18n.format("gui.cancel")));
|
||||
}
|
||||
|
||||
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.title", worldName), this.width / 2, this.height / 5 - 35, 16777215);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.seed") + " " + worldSeed, this.width / 2, this.height / 5 + 62, 0xAAAAFF);
|
||||
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.title", worldName),
|
||||
this.width / 2, this.height / 5 - 35, 16777215);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.seed") + " " + worldSeed,
|
||||
this.width / 2, this.height / 5 + 62, 0xAAAAFF);
|
||||
|
||||
int toolTipColor = 0xDDDDAA;
|
||||
if(worldRecreate.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.recreate.tooltip"), this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
}else if(worldDuplicate.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.duplicate.tooltip"), this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
}else if(worldExport.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.export.tooltip"), this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
}else if(worldConvert.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.vanilla.tooltip"), this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
}else if(worldBackup.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.clearPlayerData.tooltip"), this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
if (worldRecreate.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.recreate.tooltip"),
|
||||
this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
} else if (worldDuplicate.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.duplicate.tooltip"),
|
||||
this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
} else if (worldExport.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.export.tooltip"),
|
||||
this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
} else if (worldConvert.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.vanilla.tooltip"),
|
||||
this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
} else if (worldBackup.isMouseOver()) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.clearPlayerData.tooltip"),
|
||||
this.width / 2, this.height / 5 - 12, toolTipColor);
|
||||
}
|
||||
|
||||
|
||||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
this.mc.displayGuiScreen(selectWorld);
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
} else if (par1GuiButton.id == 1) {
|
||||
GuiCreateWorld cw = new GuiCreateWorld(selectWorld);
|
||||
cw.func_146318_a(new WorldInfo(this.levelDat.getCompoundTag("Data")));
|
||||
this.mc.displayGuiScreen(cw);
|
||||
}else if(par1GuiButton.id == 2) {
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
this.mc.displayGuiScreen(new GuiRenameWorld(this.selectWorld, this.worldName, true));
|
||||
}else if(par1GuiButton.id == 3) {
|
||||
} else if (par1GuiButton.id == 3) {
|
||||
SingleplayerServerController.exportWorld(worldName, IPCPacket05RequestData.REQUEST_LEVEL_EAG);
|
||||
this.mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(selectWorld, "singleplayer.busy.exporting.1", "singleplayer.failed.exporting.1", () -> {
|
||||
byte[] b = SingleplayerServerController.getExportResponse();
|
||||
if(b != null) {
|
||||
EagRuntime.downloadFileWithName(worldName + ".epk", b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}else if(par1GuiButton.id == 4) {
|
||||
this.mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(selectWorld, "singleplayer.busy.exporting.1",
|
||||
"singleplayer.failed.exporting.1", () -> {
|
||||
byte[] b = SingleplayerServerController.getExportResponse();
|
||||
if (b != null) {
|
||||
EagRuntime.downloadFileWithName(worldName + ".epk", b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
} else if (par1GuiButton.id == 4) {
|
||||
SingleplayerServerController.exportWorld(worldName, IPCPacket05RequestData.REQUEST_LEVEL_MCA);
|
||||
this.mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(selectWorld, "singleplayer.busy.exporting.2", "singleplayer.failed.exporting.2", () -> {
|
||||
byte[] b = SingleplayerServerController.getExportResponse();
|
||||
if(b != null) {
|
||||
EagRuntime.downloadFileWithName(worldName + ".zip", b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}else if(par1GuiButton.id == 5) {
|
||||
this.mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(selectWorld, "singleplayer.busy.exporting.2",
|
||||
"singleplayer.failed.exporting.2", () -> {
|
||||
byte[] b = SingleplayerServerController.getExportResponse();
|
||||
if (b != null) {
|
||||
EagRuntime.downloadFileWithName(worldName + ".zip", b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
} else if (par1GuiButton.id == 5) {
|
||||
this.mc.displayGuiScreen(new GuiYesNo(this, I18n.format("singleplayer.backup.clearPlayerData.warning1"),
|
||||
I18n.format("singleplayer.backup.clearPlayerData.warning2", worldName, EaglerProfile.getName()), 0));
|
||||
I18n.format("singleplayer.backup.clearPlayerData.warning2", worldName, EaglerProfile.getName()),
|
||||
0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void confirmClicked(boolean par1, int par2) {
|
||||
if(par1) {
|
||||
if (par1) {
|
||||
SingleplayerServerController.clearPlayerData(worldName);
|
||||
this.mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(this, "singleplayer.busy.clearplayers", "singleplayer.failed.clearplayers", SingleplayerServerController::isReady));
|
||||
}else {
|
||||
this.mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(this, "singleplayer.busy.clearplayers",
|
||||
"singleplayer.failed.clearplayers", SingleplayerServerController::isReady));
|
||||
} else {
|
||||
mc.displayGuiScreen(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,24 @@ import net.minecraft.client.gui.GuiScreen;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -35,29 +43,31 @@ public class GuiScreenChangeRelayTimeout extends GuiScreen {
|
|||
buttonList.clear();
|
||||
buttonList.add(new GuiButton(0, width / 2 - 100, height / 3 + 55, I18n.format("gui.done")));
|
||||
buttonList.add(new GuiButton(1, width / 2 - 100, height / 3 + 85, I18n.format("gui.cancel")));
|
||||
slider = new GuiSlider2(0, width / 2 - 100, height / 3 + 10, 200, 20, (mc.gameSettings.relayTimeout - 1) / 14.0f, 1.0f) {
|
||||
slider = new GuiSlider2(0, width / 2 - 100, height / 3 + 10, 200, 20,
|
||||
(mc.gameSettings.relayTimeout - 1) / 14.0f, 1.0f) {
|
||||
public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
|
||||
if(super.mousePressed(par1Minecraft, par2, par3)) {
|
||||
this.displayString = "" + (int)((sliderValue * 14.0f) + 1.0f) + "s";
|
||||
if (super.mousePressed(par1Minecraft, par2, par3)) {
|
||||
this.displayString = "" + (int) ((sliderValue * 14.0f) + 1.0f) + "s";
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseDragged(Minecraft par1Minecraft, int par2, int par3) {
|
||||
super.mouseDragged(par1Minecraft, par2, par3);
|
||||
this.displayString = "" + (int)((sliderValue * 14.0f) + 1.0f) + "s";
|
||||
this.displayString = "" + (int) ((sliderValue * 14.0f) + 1.0f) + "s";
|
||||
}
|
||||
};
|
||||
slider.displayString = "" + mc.gameSettings.relayTimeout + "s";
|
||||
}
|
||||
|
||||
public void actionPerformed(GuiButton btn) {
|
||||
if(btn.id == 0) {
|
||||
mc.gameSettings.relayTimeout = (int)((slider.sliderValue * 14.0f) + 1.0f);
|
||||
if (btn.id == 0) {
|
||||
mc.gameSettings.relayTimeout = (int) ((slider.sliderValue * 14.0f) + 1.0f);
|
||||
mc.gameSettings.saveOptions();
|
||||
mc.displayGuiScreen(parent);
|
||||
}else if(btn.id == 1) {
|
||||
} else if (btn.id == 1) {
|
||||
mc.displayGuiScreen(parent);
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +85,7 @@ public class GuiScreenChangeRelayTimeout extends GuiScreen {
|
|||
}
|
||||
|
||||
public void mouseReleased(int par1, int par2, int par3) {
|
||||
if(par3 == 0) {
|
||||
if (par3 == 0) {
|
||||
slider.mouseReleased(par1, par2);
|
||||
}
|
||||
super.mouseReleased(par1, par2, par3);
|
||||
|
|
|
@ -8,16 +8,24 @@ import net.minecraft.client.gui.GuiScreenServerList;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -39,22 +47,24 @@ public class GuiScreenConnectOption extends GuiScreen {
|
|||
title = I18n.format("selectServer.direct");
|
||||
prompt = I18n.format("directConnect.prompt");
|
||||
buttonList.clear();
|
||||
buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 - 60 + 90, I18n.format("directConnect.serverJoin")));
|
||||
buttonList.add(new GuiButton(2, this.width / 2 - 100, this.height / 4 - 60 + 115, I18n.format("directConnect.lanWorld")));
|
||||
buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 - 60 + 90,
|
||||
I18n.format("directConnect.serverJoin")));
|
||||
buttonList.add(new GuiButton(2, this.width / 2 - 100, this.height / 4 - 60 + 115,
|
||||
I18n.format("directConnect.lanWorld")));
|
||||
buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 - 60 + 155, I18n.format("gui.cancel")));
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
guiScreen.cancelDirectConnect();
|
||||
mc.displayGuiScreen(guiScreen);
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
} else if (par1GuiButton.id == 1) {
|
||||
mc.displayGuiScreen(new GuiScreenServerList(guiScreen, guiScreen.getSelectedServer()));
|
||||
}else if(par1GuiButton.id == 2) {
|
||||
if(LANServerController.supported()) {
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
if (LANServerController.supported()) {
|
||||
guiScreen.cancelDirectConnect();
|
||||
mc.displayGuiScreen(GuiScreenLANInfo.showLANInfoScreen(new GuiScreenLANConnect(guiScreen)));
|
||||
}else {
|
||||
} else {
|
||||
mc.displayGuiScreen(new GuiScreenLANNotSupported(this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,24 @@ import net.minecraft.client.gui.GuiTextField;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -37,9 +45,12 @@ public class GuiScreenLANConnect extends GuiScreen {
|
|||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, I18n.format("directConnect.lanWorldJoin")));
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, I18n.format("gui.cancel")));
|
||||
this.codeTextField = new GuiTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 27, 200, 20);
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12,
|
||||
I18n.format("directConnect.lanWorldJoin")));
|
||||
this.buttonList
|
||||
.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, I18n.format("gui.cancel")));
|
||||
this.codeTextField = new GuiTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 27, 200,
|
||||
20);
|
||||
this.codeTextField.setMaxStringLength(48);
|
||||
this.codeTextField.setFocused(true);
|
||||
this.codeTextField.setText(lastCode);
|
||||
|
@ -71,19 +82,23 @@ public class GuiScreenLANConnect extends GuiScreen {
|
|||
|
||||
public void drawScreen(int xx, int yy, float pt) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("selectServer.direct"), this.width / 2, this.height / 4 - 60 + 20, 16777215);
|
||||
this.drawString(this.fontRendererObj, I18n.format("directConnect.lanWorldCode"), this.width / 2 - 100, this.height / 4 + 12, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("directConnect.networkSettingsNote"), this.width / 2, this.height / 4 + 63, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("directConnect.ipGrabNote"), this.width / 2, this.height / 4 + 77, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("selectServer.direct"), this.width / 2,
|
||||
this.height / 4 - 60 + 20, 16777215);
|
||||
this.drawString(this.fontRendererObj, I18n.format("directConnect.lanWorldCode"), this.width / 2 - 100,
|
||||
this.height / 4 + 12, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("directConnect.networkSettingsNote"), this.width / 2,
|
||||
this.height / 4 + 63, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("directConnect.ipGrabNote"), this.width / 2,
|
||||
this.height / 4 + 77, 10526880);
|
||||
this.codeTextField.drawTextBox();
|
||||
super.drawScreen(xx, yy, pt);
|
||||
this.relaysButton.drawScreen(xx, yy);
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 1) {
|
||||
if (par1GuiButton.id == 1) {
|
||||
mc.displayGuiScreen(parent);
|
||||
}else if(par1GuiButton.id == 0) {
|
||||
} else if (par1GuiButton.id == 0) {
|
||||
mc.displayGuiScreen(new GuiScreenLANConnecting(parent, this.codeTextField.getText().trim()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,24 @@ import net.minecraft.util.ChatComponentText;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -61,7 +69,7 @@ public class GuiScreenLANConnecting extends GuiScreen {
|
|||
}
|
||||
|
||||
public void updateScreen() {
|
||||
if(networkManager != null) {
|
||||
if (networkManager != null) {
|
||||
if (networkManager.isChannelOpen()) {
|
||||
try {
|
||||
networkManager.processReceivedPackets();
|
||||
|
@ -72,7 +80,8 @@ public class GuiScreenLANConnecting extends GuiScreen {
|
|||
this.mc.getSession().reset();
|
||||
if (mc.currentScreen == this) {
|
||||
mc.loadWorld(null);
|
||||
mc.displayGuiScreen(new GuiDisconnected(parent, "connect.failed", new ChatComponentText("LAN Connection Refused")));
|
||||
mc.displayGuiScreen(new GuiDisconnected(parent, "connect.failed",
|
||||
new ChatComponentText("LAN Connection Refused")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,33 +90,39 @@ public class GuiScreenLANConnecting extends GuiScreen {
|
|||
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
if(completed) {
|
||||
if (completed) {
|
||||
String message = I18n.format("connect.authorizing");
|
||||
this.drawString(fontRendererObj, message, (this.width - this.fontRendererObj.getStringWidth(message)) / 2, this.height / 3 + 10, 0xFFFFFF);
|
||||
}else {
|
||||
this.drawString(fontRendererObj, message, (this.width - this.fontRendererObj.getStringWidth(message)) / 2,
|
||||
this.height / 3 + 10, 0xFFFFFF);
|
||||
} else {
|
||||
LoadingScreenRenderer ls = mc.loadingScreen;
|
||||
|
||||
String message = I18n.format("lanServer.pleaseWait");
|
||||
this.drawString(fontRendererObj, message, (this.width - this.fontRendererObj.getStringWidth(message)) / 2, this.height / 3 + 10, 0xFFFFFF);
|
||||
this.drawString(fontRendererObj, message, (this.width - this.fontRendererObj.getStringWidth(message)) / 2,
|
||||
this.height / 3 + 10, 0xFFFFFF);
|
||||
|
||||
PlatformWebRTC.startRTCLANClient();
|
||||
|
||||
if(++renderCount > 1) {
|
||||
if (++renderCount > 1) {
|
||||
RelayServerSocket sock;
|
||||
if(relay == null) {
|
||||
sock = RelayManager.relayManager.getWorkingRelay((str) -> ls.resetProgressAndMessage("Connecting: " + str), 0x02, code);
|
||||
}else {
|
||||
if (relay == null) {
|
||||
sock = RelayManager.relayManager
|
||||
.getWorkingRelay((str) -> ls.resetProgressAndMessage("Connecting: " + str), 0x02, code);
|
||||
} else {
|
||||
sock = RelayManager.relayManager.connectHandshake(relay, 0x02, code);
|
||||
}
|
||||
if(sock == null) {
|
||||
this.mc.displayGuiScreen(new GuiScreenNoRelays(parent, I18n.format("noRelay.worldNotFound1").replace("$code$", code),
|
||||
I18n.format("noRelay.worldNotFound2").replace("$code$", code), I18n.format("noRelay.worldNotFound3")));
|
||||
if (sock == null) {
|
||||
this.mc.displayGuiScreen(
|
||||
new GuiScreenNoRelays(parent, I18n.format("noRelay.worldNotFound1").replace("$code$", code),
|
||||
I18n.format("noRelay.worldNotFound2").replace("$code$", code),
|
||||
I18n.format("noRelay.worldNotFound3")));
|
||||
return;
|
||||
}
|
||||
|
||||
networkManager = LANClientNetworkManager.connectToWorld(sock, code, sock.getURI());
|
||||
if(networkManager == null) {
|
||||
this.mc.displayGuiScreen(new GuiDisconnected(parent, "connect.failed", new ChatComponentText(I18n.format("noRelay.worldFail").replace("$code$", code))));
|
||||
if (networkManager == null) {
|
||||
this.mc.displayGuiScreen(new GuiDisconnected(parent, "connect.failed",
|
||||
new ChatComponentText(I18n.format("noRelay.worldFail").replace("$code$", code))));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -117,7 +132,8 @@ public class GuiScreenLANConnecting extends GuiScreen {
|
|||
this.mc.clearTitles();
|
||||
networkManager.setConnectionState(EnumConnectionState.LOGIN);
|
||||
networkManager.setNetHandler(new NetHandlerSingleplayerLogin(networkManager, mc, parent));
|
||||
networkManager.sendPacket(new C00PacketLoginStart(this.mc.getSession().getProfile(), EaglerProfile.getSkinPacket(), EaglerProfile.getCapePacket()));
|
||||
networkManager.sendPacket(new C00PacketLoginStart(this.mc.getSession().getProfile(),
|
||||
EaglerProfile.getSkinPacket(), EaglerProfile.getCapePacket()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,24 @@ import net.minecraft.client.gui.GuiScreen;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -33,13 +41,19 @@ public class GuiScreenLANInfo extends GuiScreen {
|
|||
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("lanInfo.title"), this.width / 2, this.height / 4 - 60 + 20, 16777215);
|
||||
this.fontRendererObj.drawSplitString(I18n.format("lanInfo.desc.0") + "\n\n\n" + I18n.format("lanInfo.desc.1", I18n.format("menu.multiplayer"), I18n.format("menu.openToLan")), this.width / 2 - 100, this.height / 4 - 60 + 60, 200, -6250336);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("lanInfo.title"), this.width / 2,
|
||||
this.height / 4 - 60 + 20, 16777215);
|
||||
this.fontRendererObj
|
||||
.drawSplitString(
|
||||
I18n.format("lanInfo.desc.0") + "\n\n\n"
|
||||
+ I18n.format("lanInfo.desc.1", I18n.format("menu.multiplayer"),
|
||||
I18n.format("menu.openToLan")),
|
||||
this.width / 2 - 100, this.height / 4 - 60 + 60, 200, -6250336);
|
||||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
mc.displayGuiScreen(parent);
|
||||
}
|
||||
}
|
||||
|
@ -47,10 +61,10 @@ public class GuiScreenLANInfo extends GuiScreen {
|
|||
private static boolean hasShown = false;
|
||||
|
||||
public static GuiScreen showLANInfoScreen(GuiScreen cont) {
|
||||
if(!hasShown) {
|
||||
if (!hasShown) {
|
||||
hasShown = true;
|
||||
return new GuiScreenLANInfo(cont);
|
||||
}else {
|
||||
} else {
|
||||
return cont;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,24 @@ import net.minecraft.client.gui.GuiScreen;
|
|||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -43,25 +51,29 @@ public class GuiScreenNoRelays extends GuiScreen {
|
|||
public void initGui() {
|
||||
buttonList.clear();
|
||||
buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 - 60 + 145, I18n.format("gui.cancel")));
|
||||
buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 - 60 + 115, I18n.format("directConnect.lanWorldRelay")));
|
||||
buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 - 60 + 115,
|
||||
I18n.format("directConnect.lanWorldRelay")));
|
||||
}
|
||||
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format(title1), this.width / 2, this.height / 4 - 60 + 70, 16777215);
|
||||
if(title2 != null) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format(title2), this.width / 2, this.height / 4 - 60 + 80, 0xCCCCCC);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format(title1), this.width / 2, this.height / 4 - 60 + 70,
|
||||
16777215);
|
||||
if (title2 != null) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format(title2), this.width / 2,
|
||||
this.height / 4 - 60 + 80, 0xCCCCCC);
|
||||
}
|
||||
if(title3 != null) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format(title3), this.width / 2, this.height / 4 - 60 + 90, 0xCCCCCC);
|
||||
if (title3 != null) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format(title3), this.width / 2,
|
||||
this.height / 4 - 60 + 90, 0xCCCCCC);
|
||||
}
|
||||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
mc.displayGuiScreen(parent);
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
} else if (par1GuiButton.id == 1) {
|
||||
mc.displayGuiScreen(GuiScreenLANInfo.showLANInfoScreen(new GuiScreenRelay(parent)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,16 +16,24 @@ import net.minecraft.util.ResourceLocation;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -54,65 +62,71 @@ public class GuiScreenRelay extends GuiScreen implements GuiYesNoCallback {
|
|||
selected = -1;
|
||||
buttonList.clear();
|
||||
buttonList.add(new GuiButton(0, this.width / 2 + 54, this.height - 28, 100, 20, I18n.format("gui.done")));
|
||||
buttonList.add(new GuiButton(1, this.width / 2 - 154, this.height - 52, 100, 20, I18n.format("networkSettings.add")));
|
||||
buttonList.add(deleteRelay = new GuiButton(2, this.width / 2 - 50, this.height - 52, 100, 20, I18n.format("networkSettings.delete")));
|
||||
buttonList.add(setPrimary = new GuiButton(3, this.width / 2 + 54, this.height - 52, 100, 20, I18n.format("networkSettings.default")));
|
||||
buttonList.add(new GuiButton(4, this.width / 2 - 50, this.height - 28, 100, 20, I18n.format("networkSettings.refresh")));
|
||||
buttonList.add(new GuiButton(5, this.width / 2 - 154, this.height - 28, 100, 20, I18n.format("networkSettings.loadDefaults")));
|
||||
buttonList.add(
|
||||
new GuiButton(1, this.width / 2 - 154, this.height - 52, 100, 20, I18n.format("networkSettings.add")));
|
||||
buttonList.add(deleteRelay = new GuiButton(2, this.width / 2 - 50, this.height - 52, 100, 20,
|
||||
I18n.format("networkSettings.delete")));
|
||||
buttonList.add(setPrimary = new GuiButton(3, this.width / 2 + 54, this.height - 52, 100, 20,
|
||||
I18n.format("networkSettings.default")));
|
||||
buttonList.add(new GuiButton(4, this.width / 2 - 50, this.height - 28, 100, 20,
|
||||
I18n.format("networkSettings.refresh")));
|
||||
buttonList.add(new GuiButton(5, this.width / 2 - 154, this.height - 28, 100, 20,
|
||||
I18n.format("networkSettings.loadDefaults")));
|
||||
buttonList.add(new GuiButton(6, this.width - 100, 0, 100, 20, I18n.format("networkSettings.downloadRelay")));
|
||||
updateButtons();
|
||||
this.slots = new GuiSlotRelay(this);
|
||||
if(!hasPinged) {
|
||||
if (!hasPinged) {
|
||||
hasPinged = true;
|
||||
slots.relayManager.ping();
|
||||
}
|
||||
}
|
||||
|
||||
void updateButtons() {
|
||||
if(selected < 0) {
|
||||
if (selected < 0) {
|
||||
deleteRelay.enabled = false;
|
||||
setPrimary.enabled = false;
|
||||
}else {
|
||||
} else {
|
||||
deleteRelay.enabled = true;
|
||||
setPrimary.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(GuiButton btn) {
|
||||
if(btn.id == 0) {
|
||||
if (btn.id == 0) {
|
||||
RelayManager.relayManager.save();
|
||||
mc.displayGuiScreen(screen);
|
||||
} else if(btn.id == 1) {
|
||||
} else if (btn.id == 1) {
|
||||
addingNew = true;
|
||||
mc.displayGuiScreen(new GuiScreenAddRelay(this));
|
||||
} else if(btn.id == 2) {
|
||||
if(selected >= 0) {
|
||||
} else if (btn.id == 2) {
|
||||
if (selected >= 0) {
|
||||
RelayServer srv = RelayManager.relayManager.get(selected);
|
||||
mc.displayGuiScreen(new GuiYesNo(this, I18n.format("networkSettings.delete"), I18n.format("addRelay.removeText1") +
|
||||
EnumChatFormatting.GRAY + " '" + srv.comment + "' (" + srv.address + ")", selected));
|
||||
mc.displayGuiScreen(
|
||||
new GuiYesNo(this, I18n.format("networkSettings.delete"), I18n.format("addRelay.removeText1") +
|
||||
EnumChatFormatting.GRAY + " '" + srv.comment + "' (" + srv.address + ")", selected));
|
||||
deleting = true;
|
||||
}
|
||||
} else if(btn.id == 3) {
|
||||
if(selected >= 0) {
|
||||
} else if (btn.id == 3) {
|
||||
if (selected >= 0) {
|
||||
slots.relayManager.setPrimary(selected);
|
||||
selected = 0;
|
||||
}
|
||||
} else if(btn.id == 4) {
|
||||
} else if (btn.id == 4) {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastRefresh > 700l) {
|
||||
if (millis - lastRefresh > 700l) {
|
||||
lastRefresh = millis;
|
||||
slots.relayManager.ping();
|
||||
}
|
||||
lastRefresh += 60l;
|
||||
} else if(btn.id == 5) {
|
||||
} else if (btn.id == 5) {
|
||||
slots.relayManager.loadDefaults();
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastRefresh > 700l) {
|
||||
if (millis - lastRefresh > 700l) {
|
||||
lastRefresh = millis;
|
||||
slots.relayManager.ping();
|
||||
}
|
||||
lastRefresh += 60l;
|
||||
} else if(btn.id == 6) {
|
||||
} else if (btn.id == 6) {
|
||||
EagRuntime.downloadFileWithName("EaglerSPRelay.zip", EagRuntime.getResourceBytes("relay_download.zip"));
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +151,7 @@ public class GuiScreenRelay extends GuiScreen implements GuiYesNoCallback {
|
|||
my = par2;
|
||||
slots.drawScreen(par1, par2, par3);
|
||||
|
||||
if(tooltipString != null) {
|
||||
if (tooltipString != null) {
|
||||
int ww = mc.fontRendererObj.getStringWidth(tooltipString);
|
||||
Gui.drawRect(par1 + 1, par2 - 14, par1 + ww + 7, par2 - 2, 0xC0000000);
|
||||
screen.drawString(mc.fontRendererObj, tooltipString, par1 + 4, par2 - 12, 0xFF999999);
|
||||
|
@ -156,8 +170,11 @@ public class GuiScreenRelay extends GuiScreen implements GuiYesNoCallback {
|
|||
str = EnumChatFormatting.UNDERLINE + I18n.format("networkSettings.relayTimeoutChange");
|
||||
int w2 = fontRendererObj.getStringWidth(str);
|
||||
boolean b = par1 > w + 5 && par1 < w + 7 + w2 * 3 / 4 && par2 > 3 && par2 < 11;
|
||||
if(b) Mouse.showCursor(EnumCursorType.HAND);
|
||||
this.drawString(fontRendererObj, EnumChatFormatting.UNDERLINE + I18n.format("networkSettings.relayTimeoutChange"), 0, 0, b ? 0xCCCCCC : 0x999999);
|
||||
if (b)
|
||||
Mouse.showCursor(EnumCursorType.HAND);
|
||||
this.drawString(fontRendererObj,
|
||||
EnumChatFormatting.UNDERLINE + I18n.format("networkSettings.relayTimeoutChange"), 0, 0,
|
||||
b ? 0xCCCCCC : 0x999999);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
super.drawScreen(par1, par2, par3);
|
||||
|
@ -165,14 +182,15 @@ public class GuiScreenRelay extends GuiScreen implements GuiYesNoCallback {
|
|||
|
||||
protected void mouseClicked(int par1, int par2, int par3) {
|
||||
super.mouseClicked(par1, par2, par3);
|
||||
if(par3 == 0) {
|
||||
if (par3 == 0) {
|
||||
String str = I18n.format("networkSettings.relayTimeout") + " " + mc.gameSettings.relayTimeout;
|
||||
int w = fontRendererObj.getStringWidth(str);
|
||||
str = I18n.format("networkSettings.relayTimeoutChange");
|
||||
int w2 = fontRendererObj.getStringWidth(str);
|
||||
if(par1 > w + 5 && par1 < w + 7 + w2 * 3 / 4 && par2 > 3 && par2 < 11) {
|
||||
if (par1 > w + 5 && par1 < w + 7 + w2 * 3 / 4 && par2 > 3 && par2 < 11) {
|
||||
this.mc.displayGuiScreen(new GuiScreenChangeRelayTimeout(this));
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,15 +204,15 @@ public class GuiScreenRelay extends GuiScreen implements GuiYesNoCallback {
|
|||
boolean addNewPrimary;
|
||||
|
||||
public void confirmClicked(boolean par1, int par2) {
|
||||
if(par1) {
|
||||
if(addingNew) {
|
||||
if (par1) {
|
||||
if (addingNew) {
|
||||
RelayManager.relayManager.addNew(addNewAddr, addNewName, addNewPrimary);
|
||||
addNewAddr = null;
|
||||
addNewName = null;
|
||||
addNewPrimary = false;
|
||||
selected = -1;
|
||||
updateButtons();
|
||||
}else if(deleting) {
|
||||
} else if (deleting) {
|
||||
RelayManager.relayManager.remove(par2);
|
||||
selected = -1;
|
||||
updateButtons();
|
||||
|
|
|
@ -12,16 +12,24 @@ import net.minecraft.util.ChatComponentText;
|
|||
import net.minecraft.world.WorldSettings;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -115,7 +123,7 @@ public class GuiShareToLan extends GuiScreen {
|
|||
if (par1GuiButton.id == 102) {
|
||||
this.mc.displayGuiScreen(this.parentScreen);
|
||||
} else if (par1GuiButton.id == 104) {
|
||||
if(!mc.isDemo()) {
|
||||
if (!mc.isDemo()) {
|
||||
if (this.gameMode.equals("survival")) {
|
||||
this.gameMode = "creative";
|
||||
} else if (this.gameMode.equals("creative")) {
|
||||
|
@ -125,11 +133,11 @@ public class GuiShareToLan extends GuiScreen {
|
|||
} else {
|
||||
this.gameMode = "survival";
|
||||
}
|
||||
|
||||
|
||||
this.func_74088_g();
|
||||
}
|
||||
} else if (par1GuiButton.id == 103) {
|
||||
if(!mc.isDemo()) {
|
||||
if (!mc.isDemo()) {
|
||||
this.allowCommands = !this.allowCommands;
|
||||
this.func_74088_g();
|
||||
}
|
||||
|
@ -152,7 +160,8 @@ public class GuiShareToLan extends GuiScreen {
|
|||
LoadingScreenRenderer ls = mc.loadingScreen;
|
||||
String code = LANServerController.shareToLAN(ls::resetProgressAndMessage, worldName, hiddenToggle);
|
||||
if (code != null) {
|
||||
SingleplayerServerController.configureLAN(WorldSettings.GameType.getByName(this.gameMode), this.allowCommands);
|
||||
SingleplayerServerController.configureLAN(WorldSettings.GameType.getByName(this.gameMode),
|
||||
this.allowCommands);
|
||||
this.mc.ingameGUI.getChatGUI().printChatMessage(new ChatComponentText(I18n.format("lanServer.opened")
|
||||
.replace("$relay$", LANServerController.getCurrentURI()).replace("$code$", code)));
|
||||
} else {
|
||||
|
|
|
@ -5,16 +5,24 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.client.gui.GuiButton;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -28,7 +36,7 @@ public class GuiSlider2 extends GuiButton {
|
|||
public boolean dragging = false;
|
||||
|
||||
public GuiSlider2(int par1, int par2, int par3, int par4, int par5, float par6, float par7) {
|
||||
super(par1, par2, par3, par4, par5, (int)(par6 * par7 * 100.0F) + "%");
|
||||
super(par1, par2, par3, par4, par5, (int) (par6 * par7 * 100.0F) + "%");
|
||||
this.sliderValue = par6;
|
||||
this.sliderMax = par7;
|
||||
}
|
||||
|
@ -58,13 +66,15 @@ public class GuiSlider2 extends GuiButton {
|
|||
this.sliderValue = 1.0F;
|
||||
}
|
||||
|
||||
this.displayString = (int)(this.sliderValue * this.sliderMax * 100.0F) + "%";
|
||||
this.displayString = (int) (this.sliderValue * this.sliderMax * 100.0F) + "%";
|
||||
}
|
||||
|
||||
if(this.enabled) {
|
||||
if (this.enabled) {
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
|
||||
this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
|
||||
this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)),
|
||||
this.yPosition, 0, 66, 4, 20);
|
||||
this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)) + 4,
|
||||
this.yPosition, 196, 66, 4, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +95,7 @@ public class GuiSlider2 extends GuiButton {
|
|||
this.sliderValue = 1.0F;
|
||||
}
|
||||
|
||||
this.displayString = (int)(this.sliderValue * this.sliderMax * 100.0F) + "%";
|
||||
this.displayString = (int) (this.sliderValue * this.sliderMax * 100.0F) + "%";
|
||||
this.dragging = true;
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -10,16 +10,24 @@ import net.minecraft.client.gui.GuiSlot;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -60,7 +68,7 @@ class GuiSlotRelay extends GuiSlot {
|
|||
|
||||
@Override
|
||||
protected void drawSlot(int id, int xx, int yy, int width, int height, int ii) {
|
||||
if(id < relayManager.count()) {
|
||||
if (id < relayManager.count()) {
|
||||
this.mc.getTextureManager().bindTexture(Gui.icons);
|
||||
RelayServer srv = relayManager.get(id);
|
||||
String comment = srv.comment;
|
||||
|
@ -69,21 +77,21 @@ class GuiSlotRelay extends GuiSlot {
|
|||
String str = null;
|
||||
int h = 12;
|
||||
long ping = srv.getPing();
|
||||
if(ping == 0l) {
|
||||
if (ping == 0l) {
|
||||
var16 = 5;
|
||||
str = "No Connection";
|
||||
}else if(ping < 0l) {
|
||||
} else if (ping < 0l) {
|
||||
var15 = 1;
|
||||
var16 = (int) (Minecraft.getSystemTime() / 100L + (long) (id * 2) & 7L);
|
||||
if (var16 > 4) {
|
||||
var16 = 8 - var16;
|
||||
}
|
||||
str = "Polling...";
|
||||
}else {
|
||||
} else {
|
||||
RelayQuery.VersionMismatch vm = srv.getPingCompatible();
|
||||
if(!vm.isCompatible()) {
|
||||
if (!vm.isCompatible()) {
|
||||
var16 = 5;
|
||||
switch(vm) {
|
||||
switch (vm) {
|
||||
case CLIENT_OUTDATED:
|
||||
str = "Outdated Client!";
|
||||
break;
|
||||
|
@ -102,9 +110,9 @@ class GuiSlotRelay extends GuiSlot {
|
|||
screen.drawTexturedModalRect(0, 0, 0, 144, 16, 16);
|
||||
GlStateManager.popMatrix();
|
||||
h += 10;
|
||||
}else {
|
||||
} else {
|
||||
String pingComment = srv.getPingComment().trim();
|
||||
if(pingComment.length() > 0) {
|
||||
if (pingComment.length() > 0) {
|
||||
comment = pingComment;
|
||||
}
|
||||
str = "" + ping + "ms";
|
||||
|
@ -124,7 +132,7 @@ class GuiSlotRelay extends GuiSlot {
|
|||
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
screen.drawTexturedModalRect(xx + 205, yy, 0 + var15 * 10, 176 + var16 * 8, 10, 8);
|
||||
if(srv.isPrimary()) {
|
||||
if (srv.isPrimary()) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(xx + 4, yy + 5, 0.0f);
|
||||
GlStateManager.scale(0.8f, 0.8f, 0.8f);
|
||||
|
@ -136,11 +144,11 @@ class GuiSlotRelay extends GuiSlot {
|
|||
screen.drawString(mc.fontRendererObj, comment, xx + 22, yy + 2, 0xFFFFFFFF);
|
||||
screen.drawString(mc.fontRendererObj, srv.address, xx + 22, yy + 12, 0xFF999999);
|
||||
|
||||
if(str != null) {
|
||||
if (str != null) {
|
||||
int mx = screen.getFrameMouseX();
|
||||
int my = screen.getFrameMouseY();
|
||||
int rx = xx + 202;
|
||||
if(mx > rx && mx < rx + 13 && my > yy - 1 && my < yy + h) {
|
||||
if (mx > rx && mx < rx + 13 && my > yy - 1 && my < yy + h) {
|
||||
screen.setToolTip(str);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,16 +25,24 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -47,7 +55,8 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
|
||||
public static final int fragmentSize = 0xFF00;
|
||||
|
||||
private static final String[] initStateNames = new String[] { "PRE", "INIT", "SENT_ICE_CANDIDATE", "SENT_DESCRIPTION" };
|
||||
private static final String[] initStateNames = new String[] { "PRE", "INIT", "SENT_ICE_CANDIDATE",
|
||||
"SENT_DESCRIPTION" };
|
||||
|
||||
public final String displayCode;
|
||||
public final String displayRelay;
|
||||
|
@ -72,37 +81,41 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
return clientDisconnected ? EnumEaglerConnectionState.CLOSED : EnumEaglerConnectionState.CONNECTED;
|
||||
}
|
||||
|
||||
public static LANClientNetworkManager connectToWorld(RelayServerSocket sock, String displayCode, String displayRelay) {
|
||||
public static LANClientNetworkManager connectToWorld(RelayServerSocket sock, String displayCode,
|
||||
String displayRelay) {
|
||||
PlatformWebRTC.clearLANClientState();
|
||||
int connectState = PRE;
|
||||
IPacket pkt;
|
||||
mainLoop: while(!sock.isClosed()) {
|
||||
if((pkt = sock.readPacket()) != null) {
|
||||
if(pkt instanceof IPacket00Handshake) {
|
||||
if(connectState == PRE) {
|
||||
mainLoop: while (!sock.isClosed()) {
|
||||
if ((pkt = sock.readPacket()) != null) {
|
||||
if (pkt instanceof IPacket00Handshake) {
|
||||
if (connectState == PRE) {
|
||||
|
||||
// %%%%%% Process IPacket00Handshake %%%%%%
|
||||
// %%%%%% Process IPacket00Handshake %%%%%%
|
||||
|
||||
logger.info("Relay [{}|{}] recieved handshake, client id: {}", displayRelay, displayCode, ((IPacket00Handshake)pkt).connectionCode);
|
||||
logger.info("Relay [{}|{}] recieved handshake, client id: {}", displayRelay, displayCode,
|
||||
((IPacket00Handshake) pkt).connectionCode);
|
||||
connectState = INIT;
|
||||
|
||||
}else {
|
||||
} else {
|
||||
sock.close();
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket00Handshake in state {}", displayRelay, displayCode, initStateNames[connectState]);
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket00Handshake in state {}", displayRelay,
|
||||
displayCode, initStateNames[connectState]);
|
||||
return null;
|
||||
}
|
||||
}else if(pkt instanceof IPacket01ICEServers) {
|
||||
if(connectState == INIT) {
|
||||
} else if (pkt instanceof IPacket01ICEServers) {
|
||||
if (connectState == INIT) {
|
||||
|
||||
// %%%%%% Process IPacket01ICEServers %%%%%%
|
||||
// %%%%%% Process IPacket01ICEServers %%%%%%
|
||||
|
||||
IPacket01ICEServers ipkt = (IPacket01ICEServers) pkt;
|
||||
|
||||
// print servers
|
||||
logger.info("Relay [{}|{}] provided ICE servers:", displayRelay, displayCode);
|
||||
List<String> servers = new ArrayList();
|
||||
for(ICEServerSet.RelayServer srv : ipkt.servers) {
|
||||
logger.info("Relay [{}|{}] {}: {}", displayRelay, displayCode, srv.type.name(), srv.address);
|
||||
for (ICEServerSet.RelayServer srv : ipkt.servers) {
|
||||
logger.info("Relay [{}|{}] {}: {}", displayRelay, displayCode, srv.type.name(),
|
||||
srv.address);
|
||||
servers.add(srv.getICEString());
|
||||
}
|
||||
|
||||
|
@ -113,7 +126,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
long lm = System.currentTimeMillis();
|
||||
do {
|
||||
String c = PlatformWebRTC.clientLANAwaitDescription();
|
||||
if(c != null) {
|
||||
if (c != null) {
|
||||
logger.info("Relay [{}|{}] client sent description", displayRelay, displayCode);
|
||||
|
||||
// 'this.descriptionHandler' was called, send result:
|
||||
|
@ -123,22 +136,23 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
continue mainLoop;
|
||||
}
|
||||
EagUtils.sleep(20l);
|
||||
}while(System.currentTimeMillis() - lm < 5000l);
|
||||
} while (System.currentTimeMillis() - lm < 5000l);
|
||||
|
||||
// no description was sent
|
||||
sock.close();
|
||||
logger.error("Relay [{}|{}] client provide description timeout", displayRelay, displayCode);
|
||||
return null;
|
||||
|
||||
}else {
|
||||
} else {
|
||||
sock.close();
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket01ICEServers in state {}", displayRelay, displayCode, initStateNames[connectState]);
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket01ICEServers in state {}", displayRelay,
|
||||
displayCode, initStateNames[connectState]);
|
||||
return null;
|
||||
}
|
||||
}else if(pkt instanceof IPacket03ICECandidate) {
|
||||
if(connectState == SENT_ICE_CANDIDATE) {
|
||||
} else if (pkt instanceof IPacket03ICECandidate) {
|
||||
if (connectState == SENT_ICE_CANDIDATE) {
|
||||
|
||||
// %%%%%% Process IPacket03ICECandidate %%%%%%
|
||||
// %%%%%% Process IPacket03ICECandidate %%%%%%
|
||||
|
||||
IPacket03ICECandidate ipkt = (IPacket03ICECandidate) pkt;
|
||||
|
||||
|
@ -149,7 +163,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
// await result
|
||||
long lm = System.currentTimeMillis();
|
||||
do {
|
||||
if(PlatformWebRTC.clientLANAwaitChannel()) {
|
||||
if (PlatformWebRTC.clientLANAwaitChannel()) {
|
||||
logger.info("Relay [{}|{}] client opened data channel", displayRelay, displayCode);
|
||||
|
||||
// 'this.remoteDataChannelHandler' was called, success
|
||||
|
@ -159,7 +173,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
|
||||
}
|
||||
EagUtils.sleep(20l);
|
||||
}while(System.currentTimeMillis() - lm < 5000l);
|
||||
} while (System.currentTimeMillis() - lm < 5000l);
|
||||
|
||||
// no channel was opened
|
||||
sock.writePacket(new IPacket06ClientFailure(ipkt.peerId));
|
||||
|
@ -167,15 +181,16 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
logger.error("Relay [{}|{}] client open data channel timeout", displayRelay, displayCode);
|
||||
return null;
|
||||
|
||||
}else {
|
||||
} else {
|
||||
sock.close();
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket03ICECandidate in state {}", displayRelay, displayCode, initStateNames[connectState]);
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket03ICECandidate in state {}", displayRelay,
|
||||
displayCode, initStateNames[connectState]);
|
||||
return null;
|
||||
}
|
||||
}else if(pkt instanceof IPacket04Description) {
|
||||
if(connectState == SENT_DESCRIPTION) {
|
||||
} else if (pkt instanceof IPacket04Description) {
|
||||
if (connectState == SENT_DESCRIPTION) {
|
||||
|
||||
// %%%%%% Process IPacket04Description %%%%%%
|
||||
// %%%%%% Process IPacket04Description %%%%%%
|
||||
|
||||
IPacket04Description ipkt = (IPacket04Description) pkt;
|
||||
|
||||
|
@ -187,7 +202,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
long lm = System.currentTimeMillis();
|
||||
do {
|
||||
String c = PlatformWebRTC.clientLANAwaitICECandidate();
|
||||
if(c != null) {
|
||||
if (c != null) {
|
||||
logger.info("Relay [{}|{}] client sent ICE candidate", displayRelay, displayCode);
|
||||
|
||||
// 'this.iceCandidateHandler' was called, send result:
|
||||
|
@ -197,36 +212,39 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
continue mainLoop;
|
||||
}
|
||||
EagUtils.sleep(20l);
|
||||
}while(System.currentTimeMillis() - lm < 5000l);
|
||||
} while (System.currentTimeMillis() - lm < 5000l);
|
||||
|
||||
// no ice candidates were sent
|
||||
sock.close();
|
||||
logger.error("Relay [{}|{}] client provide ICE candidate timeout", displayRelay, displayCode);
|
||||
return null;
|
||||
|
||||
}else {
|
||||
} else {
|
||||
sock.close();
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket04Description in state {}", displayRelay, displayCode, initStateNames[connectState]);
|
||||
logger.error("Relay [{}|{}] unexpected packet: IPacket04Description in state {}", displayRelay,
|
||||
displayCode, initStateNames[connectState]);
|
||||
return null;
|
||||
}
|
||||
}else if(pkt instanceof IPacketFFErrorCode) {
|
||||
} else if (pkt instanceof IPacketFFErrorCode) {
|
||||
|
||||
// %%%%%% Process IPacketFFErrorCode %%%%%%
|
||||
// %%%%%% Process IPacketFFErrorCode %%%%%%
|
||||
|
||||
IPacketFFErrorCode ipkt = (IPacketFFErrorCode) pkt;
|
||||
logger.error("Relay [{}|{}] connection failed: {}({}): {}", displayRelay, displayCode, IPacketFFErrorCode.code2string(ipkt.code), ipkt.code, ipkt.desc);
|
||||
logger.error("Relay [{}|{}] connection failed: {}({}): {}", displayRelay, displayCode,
|
||||
IPacketFFErrorCode.code2string(ipkt.code), ipkt.code, ipkt.desc);
|
||||
Throwable t;
|
||||
while((t = sock.getException()) != null) {
|
||||
while ((t = sock.getException()) != null) {
|
||||
logger.error(t);
|
||||
}
|
||||
sock.close();
|
||||
return null;
|
||||
|
||||
}else {
|
||||
} else {
|
||||
|
||||
// %%%%%% Unexpected Packet %%%%%%
|
||||
// %%%%%% Unexpected Packet %%%%%%
|
||||
|
||||
logger.error("Relay [{}|{}] unexpected packet: {}", displayRelay, displayCode, pkt.getClass().getSimpleName());
|
||||
logger.error("Relay [{}|{}] unexpected packet: {}", displayRelay, displayCode,
|
||||
pkt.getClass().getSimpleName());
|
||||
sock.close();
|
||||
return null;
|
||||
}
|
||||
|
@ -238,7 +256,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
|
||||
@Override
|
||||
public void sendPacket(Packet pkt) {
|
||||
if(!isChannelOpen()) {
|
||||
if (!isChannelOpen()) {
|
||||
logger.error("Packet was sent on a closed connection: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
@ -246,7 +264,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
int i;
|
||||
try {
|
||||
i = packetState.getPacketId(EnumPacketDirection.SERVERBOUND, pkt);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Incorrect packet for state: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
@ -255,22 +273,22 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
temporaryBuffer.writeVarIntToBuffer(i);
|
||||
try {
|
||||
pkt.writePacketData(temporaryBuffer);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Failed to write packet {}!", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
int len = temporaryBuffer.readableBytes();
|
||||
int fragmentSizeN1 = fragmentSize - 1;
|
||||
if(len > fragmentSizeN1) {
|
||||
if (len > fragmentSizeN1) {
|
||||
do {
|
||||
int readLen = len > fragmentSizeN1 ? fragmentSizeN1 : len;
|
||||
byte[] frag = new byte[readLen + 1];
|
||||
temporaryBuffer.readBytes(frag, 1, readLen);
|
||||
frag[0] = temporaryBuffer.readableBytes() == 0 ? (byte)0 : (byte)1;
|
||||
frag[0] = temporaryBuffer.readableBytes() == 0 ? (byte) 0 : (byte) 1;
|
||||
PlatformWebRTC.clientLANSendPacket(frag);
|
||||
}while((len = temporaryBuffer.readableBytes()) > 0);
|
||||
}else {
|
||||
} while ((len = temporaryBuffer.readableBytes()) > 0);
|
||||
} else {
|
||||
byte[] bytes = new byte[len + 1];
|
||||
bytes[0] = 0;
|
||||
temporaryBuffer.readBytes(bytes, 1, len);
|
||||
|
@ -295,30 +313,30 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
|
||||
@Override
|
||||
public void processReceivedPackets() throws IOException {
|
||||
if(this.nethandler != null) {
|
||||
if (this.nethandler != null) {
|
||||
List<byte[]> packets = PlatformWebRTC.clientLANReadAllPacket();
|
||||
if(packets == null) {
|
||||
if (packets == null) {
|
||||
return;
|
||||
}
|
||||
for(int k = 0, l = packets.size(); k < l; ++k) {
|
||||
for (int k = 0, l = packets.size(); k < l; ++k) {
|
||||
byte[] data = packets.get(k);
|
||||
byte[] fullData;
|
||||
boolean compressed = false;
|
||||
|
||||
if (data[0] == 0 || data[0] == 2) {
|
||||
if(fragmentedPacket.isEmpty()) {
|
||||
if (fragmentedPacket.isEmpty()) {
|
||||
fullData = new byte[data.length - 1];
|
||||
System.arraycopy(data, 1, fullData, 0, fullData.length);
|
||||
}else {
|
||||
} else {
|
||||
fragmentedPacket.add(data);
|
||||
int len = 0;
|
||||
int fragCount = fragmentedPacket.size();
|
||||
for(int i = 0; i < fragCount; ++i) {
|
||||
for (int i = 0; i < fragCount; ++i) {
|
||||
len += fragmentedPacket.get(i).length - 1;
|
||||
}
|
||||
fullData = new byte[len];
|
||||
len = 0;
|
||||
for(int i = 0; i < fragCount; ++i) {
|
||||
for (int i = 0; i < fragCount; ++i) {
|
||||
byte[] f = fragmentedPacket.get(i);
|
||||
System.arraycopy(f, 1, fullData, len, f.length - 1);
|
||||
len += f.length - 1;
|
||||
|
@ -330,12 +348,12 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
fragmentedPacket.add(data);
|
||||
continue;
|
||||
} else {
|
||||
logger.error("Recieved {} byte fragment of unknown type: {}", data.length, ((int)data[0] & 0xFF));
|
||||
logger.error("Recieved {} byte fragment of unknown type: {}", data.length, ((int) data[0] & 0xFF));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(compressed) {
|
||||
if(fullData.length < 4) {
|
||||
if (compressed) {
|
||||
if (fullData.length < 4) {
|
||||
throw new IOException("Recieved invalid " + fullData.length + " byte compressed packet");
|
||||
}
|
||||
EaglerInputStream bi = new EaglerInputStream(fullData);
|
||||
|
@ -348,9 +366,10 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
}
|
||||
}
|
||||
|
||||
if(firstPacket) {
|
||||
if (firstPacket) {
|
||||
// 1.5 kick packet
|
||||
if(fullData.length == 31 && fullData[0] == (byte)0xFF && fullData[1] == (byte)0x00 && fullData[2] == (byte)0x0E) {
|
||||
if (fullData.length == 31 && fullData[0] == (byte) 0xFF && fullData[1] == (byte) 0x00
|
||||
&& fullData[2] == (byte) 0x0E) {
|
||||
logger.error("Detected a 1.5 LAN server!");
|
||||
this.closeChannel(new ChatComponentTranslation("singleplayer.outdatedLANServerKick"));
|
||||
firstPacket = false;
|
||||
|
@ -367,24 +386,26 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
Packet pkt;
|
||||
try {
|
||||
pkt = packetState.getPacket(EnumPacketDirection.CLIENTBOUND, pktId);
|
||||
}catch(IllegalAccessException | InstantiationException ex) {
|
||||
} catch (IllegalAccessException | InstantiationException ex) {
|
||||
throw new IOException("Recieved a packet with type " + pktId + " which is invalid!");
|
||||
}
|
||||
|
||||
if(pkt == null) {
|
||||
throw new IOException("Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
if (pkt == null) {
|
||||
throw new IOException(
|
||||
"Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
}
|
||||
|
||||
try {
|
||||
pkt.readPacketData(input);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new IOException("Failed to read packet type '" + pkt.getClass().getSimpleName() + "'", t);
|
||||
}
|
||||
|
||||
try {
|
||||
pkt.processPacket(nethandler);
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.", pkt.getClass().getSimpleName());
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.",
|
||||
pkt.getClass().getSimpleName());
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
|
@ -393,10 +414,10 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
|
||||
@Override
|
||||
public void closeChannel(IChatComponent reason) {
|
||||
if(!PlatformWebRTC.clientLANClosed()) {
|
||||
if (!PlatformWebRTC.clientLANClosed()) {
|
||||
PlatformWebRTC.clientLANCloseConnection();
|
||||
}
|
||||
if(nethandler != null) {
|
||||
if (nethandler != null) {
|
||||
nethandler.onDisconnect(reason);
|
||||
}
|
||||
clientDisconnected = true;
|
||||
|
@ -404,7 +425,7 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
|||
|
||||
@Override
|
||||
public boolean checkDisconnected() {
|
||||
if(PlatformWebRTC.clientLANClosed()) {
|
||||
if (PlatformWebRTC.clientLANClosed()) {
|
||||
clientDisconnected = false;
|
||||
try {
|
||||
processReceivedPackets(); // catch kick message
|
||||
|
|
|
@ -14,16 +14,24 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket03ICECandidate;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket04Description;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -45,115 +53,123 @@ class LANClientPeer {
|
|||
}
|
||||
|
||||
protected void handleICECandidates(String candidates) {
|
||||
if(state == SENT_DESCRIPTION) {
|
||||
if (state == SENT_DESCRIPTION) {
|
||||
PlatformWebRTC.serverLANPeerICECandidates(clientId, candidates);
|
||||
long millis = System.currentTimeMillis();
|
||||
do {
|
||||
LANPeerEvent evt;
|
||||
if((evt = PlatformWebRTC.serverLANGetEvent(clientId)) != null) {
|
||||
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
|
||||
LANServerController.lanRelaySocket.writePacket(new IPacket03ICECandidate(clientId, ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates));
|
||||
if ((evt = PlatformWebRTC.serverLANGetEvent(clientId)) != null) {
|
||||
if (evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
|
||||
LANServerController.lanRelaySocket.writePacket(new IPacket03ICECandidate(clientId,
|
||||
((LANPeerEvent.LANPeerICECandidateEvent) evt).candidates));
|
||||
state = SENT_ICE_CANDIDATE;
|
||||
return;
|
||||
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
} else if (evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
logger.error("LAN client '{}' disconnected while waiting for server ICE candidates", clientId);
|
||||
}else {
|
||||
} else {
|
||||
logger.error("LAN client '{}' had an accident: {}", clientId, evt.getClass().getSimpleName());
|
||||
}
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
EagUtils.sleep(20l);
|
||||
}while(System.currentTimeMillis() - millis < 5000l);
|
||||
} while (System.currentTimeMillis() - millis < 5000l);
|
||||
logger.error("Getting server ICE candidates for '{}' timed out!", clientId);
|
||||
disconnect();
|
||||
}else {
|
||||
logger.error("Relay [{}] unexpected IPacket03ICECandidate for '{}'", LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected IPacket03ICECandidate for '{}'",
|
||||
LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleDescription(String description) {
|
||||
if(state == PRE) {
|
||||
if (state == PRE) {
|
||||
PlatformWebRTC.serverLANPeerDescription(clientId, description);
|
||||
long millis = System.currentTimeMillis();
|
||||
do {
|
||||
LANPeerEvent evt;
|
||||
if((evt = PlatformWebRTC.serverLANGetEvent(clientId)) != null) {
|
||||
if(evt instanceof LANPeerEvent.LANPeerDescriptionEvent) {
|
||||
LANServerController.lanRelaySocket.writePacket(new IPacket04Description(clientId, ((LANPeerEvent.LANPeerDescriptionEvent)evt).description));
|
||||
if ((evt = PlatformWebRTC.serverLANGetEvent(clientId)) != null) {
|
||||
if (evt instanceof LANPeerEvent.LANPeerDescriptionEvent) {
|
||||
LANServerController.lanRelaySocket.writePacket(new IPacket04Description(clientId,
|
||||
((LANPeerEvent.LANPeerDescriptionEvent) evt).description));
|
||||
state = SENT_DESCRIPTION;
|
||||
return;
|
||||
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
} else if (evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
logger.error("LAN client '{}' disconnected while waiting for server description", clientId);
|
||||
}else {
|
||||
} else {
|
||||
logger.error("LAN client '{}' had an accident: {}", clientId, evt.getClass().getSimpleName());
|
||||
}
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
EagUtils.sleep(20l);
|
||||
}while(System.currentTimeMillis() - millis < 5000l);
|
||||
} while (System.currentTimeMillis() - millis < 5000l);
|
||||
logger.error("Getting server description for '{}' timed out!", clientId);
|
||||
disconnect();
|
||||
}else {
|
||||
logger.error("Relay [{}] unexpected IPacket04Description for '{}'", LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected IPacket04Description for '{}'",
|
||||
LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleSuccess() {
|
||||
if(state == SENT_ICE_CANDIDATE) {
|
||||
if (state == SENT_ICE_CANDIDATE) {
|
||||
long millis = System.currentTimeMillis();
|
||||
do {
|
||||
LANPeerEvent evt;
|
||||
while((evt = PlatformWebRTC.serverLANGetEvent(clientId)) != null && evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
|
||||
while ((evt = PlatformWebRTC.serverLANGetEvent(clientId)) != null
|
||||
&& evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
|
||||
// skip ice candidates
|
||||
}
|
||||
if(evt != null) {
|
||||
if(evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
|
||||
if (evt != null) {
|
||||
if (evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
|
||||
SingleplayerServerController.openPlayerChannel(clientId);
|
||||
state = CONNECTED;
|
||||
return;
|
||||
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
} else if (evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
logger.error("LAN client '{}' disconnected while waiting for connection", clientId);
|
||||
}else {
|
||||
} else {
|
||||
logger.error("LAN client '{}' had an accident: {}", clientId, evt.getClass().getSimpleName());
|
||||
}
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
EagUtils.sleep(20l);
|
||||
}while(System.currentTimeMillis() - millis < 5000l);
|
||||
} while (System.currentTimeMillis() - millis < 5000l);
|
||||
logger.error("Getting server description for '{}' timed out!", clientId);
|
||||
disconnect();
|
||||
}else {
|
||||
logger.error("Relay [{}] unexpected IPacket05ClientSuccess for '{}'", LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected IPacket05ClientSuccess for '{}'",
|
||||
LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleFailure() {
|
||||
if(state == SENT_ICE_CANDIDATE) {
|
||||
if (state == SENT_ICE_CANDIDATE) {
|
||||
logger.error("Client '{}' failed to connect", clientId);
|
||||
disconnect();
|
||||
}else {
|
||||
logger.error("Relay [{}] unexpected IPacket06ClientFailure for '{}'", LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected IPacket06ClientFailure for '{}'",
|
||||
LANServerController.lanRelaySocket.getURI(), clientId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void update() {
|
||||
if(state == CONNECTED) {
|
||||
if (state == CONNECTED) {
|
||||
List<LANPeerEvent> l = PlatformWebRTC.serverLANGetAllEvent(clientId);
|
||||
if(l == null) {
|
||||
if (l == null) {
|
||||
return;
|
||||
}
|
||||
Iterator<LANPeerEvent> itr = l.iterator();
|
||||
while(state == CONNECTED && itr.hasNext()) {
|
||||
while (state == CONNECTED && itr.hasNext()) {
|
||||
LANPeerEvent evt = itr.next();
|
||||
if(evt instanceof LANPeerEvent.LANPeerPacketEvent) {
|
||||
ClientPlatformSingleplayer.sendPacket(new IPCPacketData(clientId, ((LANPeerEvent.LANPeerPacketEvent)evt).payload));
|
||||
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
if (evt instanceof LANPeerEvent.LANPeerPacketEvent) {
|
||||
ClientPlatformSingleplayer
|
||||
.sendPacket(new IPCPacketData(clientId, ((LANPeerEvent.LANPeerPacketEvent) evt).payload));
|
||||
} else if (evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
|
||||
logger.info("LAN client '{}' disconnected", clientId);
|
||||
disconnect();
|
||||
}else {
|
||||
} else {
|
||||
logger.error("LAN client '{}' had an accident: {}", clientId, evt.getClass().getSimpleName());
|
||||
disconnect();
|
||||
}
|
||||
|
@ -162,8 +178,8 @@ class LANClientPeer {
|
|||
}
|
||||
|
||||
protected void disconnect() {
|
||||
if(!dead) {
|
||||
if(state == CONNECTED) {
|
||||
if (!dead) {
|
||||
if (state == CONNECTED) {
|
||||
SingleplayerServerController.closePlayerChannel(clientId);
|
||||
}
|
||||
state = CLOSED;
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.lan;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -18,12 +26,12 @@ package net.lax1dude.eaglercraft.v1_8.sp.lan;
|
|||
public interface LANPeerEvent {
|
||||
|
||||
String getPeerId();
|
||||
|
||||
|
||||
public static class LANPeerICECandidateEvent implements LANPeerEvent {
|
||||
|
||||
|
||||
public final String clientId;
|
||||
public final String candidates;
|
||||
|
||||
|
||||
public LANPeerICECandidateEvent(String clientId, String candidates) {
|
||||
this.clientId = clientId;
|
||||
this.candidates = candidates;
|
||||
|
@ -33,14 +41,14 @@ public interface LANPeerEvent {
|
|||
public String getPeerId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class LANPeerDescriptionEvent implements LANPeerEvent {
|
||||
|
||||
|
||||
public final String clientId;
|
||||
public final String description;
|
||||
|
||||
|
||||
public LANPeerDescriptionEvent(String clientId, String description) {
|
||||
this.clientId = clientId;
|
||||
this.description = description;
|
||||
|
@ -50,13 +58,13 @@ public interface LANPeerEvent {
|
|||
public String getPeerId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class LANPeerDataChannelEvent implements LANPeerEvent {
|
||||
|
||||
|
||||
public final String clientId;
|
||||
|
||||
|
||||
public LANPeerDataChannelEvent(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
@ -65,14 +73,14 @@ public interface LANPeerEvent {
|
|||
public String getPeerId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class LANPeerPacketEvent implements LANPeerEvent {
|
||||
|
||||
|
||||
public final String clientId;
|
||||
public final byte[] payload;
|
||||
|
||||
|
||||
public LANPeerPacketEvent(String clientId, byte[] payload) {
|
||||
this.clientId = clientId;
|
||||
this.payload = payload;
|
||||
|
@ -82,13 +90,13 @@ public interface LANPeerEvent {
|
|||
public String getPeerId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class LANPeerDisconnectEvent implements LANPeerEvent {
|
||||
|
||||
|
||||
public final String clientId;
|
||||
|
||||
|
||||
public LANPeerDisconnectEvent(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
@ -97,7 +105,7 @@ public interface LANPeerEvent {
|
|||
public String getPeerId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,16 +16,24 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayServerSocket;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.*;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -42,45 +50,47 @@ public class LANServerController {
|
|||
|
||||
public static String shareToLAN(Consumer<String> progressCallback, String worldName, boolean worldHidden) {
|
||||
currentCode = null;
|
||||
RelayServerSocket sock = RelayManager.relayManager.getWorkingRelay((str) -> progressCallback.accept("Connecting: " + str),
|
||||
RelayServerSocket sock = RelayManager.relayManager.getWorkingRelay(
|
||||
(str) -> progressCallback.accept("Connecting: " + str),
|
||||
RelayManager.preferredRelayVersion, worldName + (worldHidden ? ";1" : ";0"));
|
||||
if(sock == null) {
|
||||
if (sock == null) {
|
||||
lanRelaySocket = null;
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
progressCallback.accept("Opening: " + sock.getURI());
|
||||
IPacket00Handshake hs = (IPacket00Handshake)sock.readPacket();
|
||||
IPacket00Handshake hs = (IPacket00Handshake) sock.readPacket();
|
||||
lanRelaySocket = sock;
|
||||
String code = hs.connectionCode;
|
||||
logger.info("Relay [{}] connected as 'server', code: {}", sock.getURI(), code);
|
||||
progressCallback.accept("Opened '" + code + "' on " + sock.getURI());
|
||||
long millis = System.currentTimeMillis();
|
||||
do {
|
||||
if(sock.isClosed()) {
|
||||
if (sock.isClosed()) {
|
||||
logger.info("Relay [{}] connection lost", sock.getURI());
|
||||
lanRelaySocket = null;
|
||||
return null;
|
||||
}
|
||||
IPacket pkt = sock.readPacket();
|
||||
if(pkt != null) {
|
||||
if(pkt instanceof IPacket01ICEServers) {
|
||||
IPacket01ICEServers ipkt = (IPacket01ICEServers)pkt;
|
||||
if (pkt != null) {
|
||||
if (pkt instanceof IPacket01ICEServers) {
|
||||
IPacket01ICEServers ipkt = (IPacket01ICEServers) pkt;
|
||||
logger.info("Relay [{}] provided ICE servers:", sock.getURI());
|
||||
currentICEServers.clear();
|
||||
for(net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.ICEServerSet.RelayServer srv : ipkt.servers) {
|
||||
for (net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.ICEServerSet.RelayServer srv : ipkt.servers) {
|
||||
logger.info("Relay [{}] {}: {}", sock.getURI(), srv.type.name(), srv.address);
|
||||
currentICEServers.add(srv.getICEString());
|
||||
}
|
||||
PlatformWebRTC.serverLANInitializeServer(currentICEServers.toArray(new String[currentICEServers.size()]));
|
||||
PlatformWebRTC.serverLANInitializeServer(
|
||||
currentICEServers.toArray(new String[currentICEServers.size()]));
|
||||
return currentCode = code;
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected packet: {}", sock.getURI(), pkt.getClass().getSimpleName());
|
||||
closeLAN();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
EagUtils.sleep(50l);
|
||||
}while(System.currentTimeMillis() - millis < 1000l);
|
||||
} while (System.currentTimeMillis() - millis < 1000l);
|
||||
logger.info("Relay [{}] relay provide ICE servers timeout", sock.getURI());
|
||||
closeLAN();
|
||||
return null;
|
||||
|
@ -104,7 +114,7 @@ public class LANServerController {
|
|||
}
|
||||
|
||||
public static void closeLANNoKick() {
|
||||
if(lanRelaySocket != null) {
|
||||
if (lanRelaySocket != null) {
|
||||
lanRelaySocket.close();
|
||||
lanRelaySocket = null;
|
||||
currentCode = null;
|
||||
|
@ -113,7 +123,7 @@ public class LANServerController {
|
|||
|
||||
public static void cleanupLAN() {
|
||||
Iterator<LANClientPeer> itr = clients.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
while (itr.hasNext()) {
|
||||
itr.next().disconnect();
|
||||
}
|
||||
clients.clear();
|
||||
|
@ -134,68 +144,75 @@ public class LANServerController {
|
|||
private static final Map<String, LANClientPeer> clients = new HashMap();
|
||||
|
||||
public static void updateLANServer() {
|
||||
if(lanRelaySocket != null) {
|
||||
if (lanRelaySocket != null) {
|
||||
IPacket pkt;
|
||||
while((pkt = lanRelaySocket.readPacket()) != null) {
|
||||
if(pkt instanceof IPacket02NewClient) {
|
||||
while ((pkt = lanRelaySocket.readPacket()) != null) {
|
||||
if (pkt instanceof IPacket02NewClient) {
|
||||
IPacket02NewClient ipkt = (IPacket02NewClient) pkt;
|
||||
if(clients.containsKey(ipkt.clientId)) {
|
||||
logger.error("Relay [{}] relay provided duplicate client '{}'", lanRelaySocket.getURI(), ipkt.clientId);
|
||||
}else {
|
||||
if (clients.containsKey(ipkt.clientId)) {
|
||||
logger.error("Relay [{}] relay provided duplicate client '{}'", lanRelaySocket.getURI(),
|
||||
ipkt.clientId);
|
||||
} else {
|
||||
clients.put(ipkt.clientId, new LANClientPeer(ipkt.clientId));
|
||||
}
|
||||
}else if(pkt instanceof IPacket03ICECandidate) {
|
||||
} else if (pkt instanceof IPacket03ICECandidate) {
|
||||
IPacket03ICECandidate ipkt = (IPacket03ICECandidate) pkt;
|
||||
LANClientPeer c = clients.get(ipkt.peerId);
|
||||
if(c != null) {
|
||||
if (c != null) {
|
||||
c.handleICECandidates(ipkt.candidate);
|
||||
}else {
|
||||
logger.error("Relay [{}] relay sent IPacket03ICECandidate for unknown client '{}'", lanRelaySocket.getURI(), ipkt.peerId);
|
||||
} else {
|
||||
logger.error("Relay [{}] relay sent IPacket03ICECandidate for unknown client '{}'",
|
||||
lanRelaySocket.getURI(), ipkt.peerId);
|
||||
}
|
||||
}else if(pkt instanceof IPacket04Description) {
|
||||
} else if (pkt instanceof IPacket04Description) {
|
||||
IPacket04Description ipkt = (IPacket04Description) pkt;
|
||||
LANClientPeer c = clients.get(ipkt.peerId);
|
||||
if(c != null) {
|
||||
if (c != null) {
|
||||
c.handleDescription(ipkt.description);
|
||||
}else {
|
||||
logger.error("Relay [{}] relay sent IPacket04Description for unknown client '{}'", lanRelaySocket.getURI(), ipkt.peerId);
|
||||
} else {
|
||||
logger.error("Relay [{}] relay sent IPacket04Description for unknown client '{}'",
|
||||
lanRelaySocket.getURI(), ipkt.peerId);
|
||||
}
|
||||
}else if(pkt instanceof IPacket05ClientSuccess) {
|
||||
} else if (pkt instanceof IPacket05ClientSuccess) {
|
||||
IPacket05ClientSuccess ipkt = (IPacket05ClientSuccess) pkt;
|
||||
LANClientPeer c = clients.get(ipkt.clientId);
|
||||
if(c != null) {
|
||||
if (c != null) {
|
||||
c.handleSuccess();
|
||||
}else {
|
||||
logger.error("Relay [{}] relay sent IPacket05ClientSuccess for unknown client '{}'", lanRelaySocket.getURI(), ipkt.clientId);
|
||||
} else {
|
||||
logger.error("Relay [{}] relay sent IPacket05ClientSuccess for unknown client '{}'",
|
||||
lanRelaySocket.getURI(), ipkt.clientId);
|
||||
}
|
||||
}else if(pkt instanceof IPacket06ClientFailure) {
|
||||
} else if (pkt instanceof IPacket06ClientFailure) {
|
||||
IPacket06ClientFailure ipkt = (IPacket06ClientFailure) pkt;
|
||||
LANClientPeer c = clients.get(ipkt.clientId);
|
||||
if(c != null) {
|
||||
if (c != null) {
|
||||
c.handleFailure();
|
||||
}else {
|
||||
logger.error("Relay [{}] relay sent IPacket06ClientFailure for unknown client '{}'", lanRelaySocket.getURI(), ipkt.clientId);
|
||||
} else {
|
||||
logger.error("Relay [{}] relay sent IPacket06ClientFailure for unknown client '{}'",
|
||||
lanRelaySocket.getURI(), ipkt.clientId);
|
||||
}
|
||||
}else if(pkt instanceof IPacketFFErrorCode) {
|
||||
} else if (pkt instanceof IPacketFFErrorCode) {
|
||||
IPacketFFErrorCode ipkt = (IPacketFFErrorCode) pkt;
|
||||
logger.error("Relay [{}] error code thrown: {}({}): {}", lanRelaySocket.getURI(), IPacketFFErrorCode.code2string(ipkt.code), ipkt.code, ipkt.desc);
|
||||
logger.error("Relay [{}] error code thrown: {}({}): {}", lanRelaySocket.getURI(),
|
||||
IPacketFFErrorCode.code2string(ipkt.code), ipkt.code, ipkt.desc);
|
||||
Throwable t;
|
||||
while((t = lanRelaySocket.getException()) != null) {
|
||||
while ((t = lanRelaySocket.getException()) != null) {
|
||||
logger.error(t);
|
||||
}
|
||||
}else {
|
||||
logger.error("Relay [{}] unexpected packet: {}", lanRelaySocket.getURI(), pkt.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected packet: {}", lanRelaySocket.getURI(),
|
||||
pkt.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
if(lanRelaySocket.isClosed()) {
|
||||
if (lanRelaySocket.isClosed()) {
|
||||
lanRelaySocket = null;
|
||||
}
|
||||
}
|
||||
Iterator<LANClientPeer> itr = clients.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
while (itr.hasNext()) {
|
||||
LANClientPeer cl = itr.next();
|
||||
cl.update();
|
||||
if(cl.dead) {
|
||||
if (cl.dead) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,72 +16,80 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayWorldsQuery;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket07LocalWorlds;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class LANServerList {
|
||||
|
||||
|
||||
private final List<LanServer> lanServersList = new LinkedList();
|
||||
private final Map<String, RelayWorldsQuery> lanServersQueryList = new LinkedHashMap();
|
||||
private final Set<String> deadURIs = new HashSet();
|
||||
|
||||
|
||||
private long lastRefresh = 0l;
|
||||
private int refreshCounter = 0;
|
||||
|
||||
|
||||
public boolean update() {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastRefresh > 20000l) {
|
||||
if(++refreshCounter < 10) {
|
||||
if (millis - lastRefresh > 20000l) {
|
||||
if (++refreshCounter < 10) {
|
||||
refresh();
|
||||
}else {
|
||||
} else {
|
||||
lastRefresh = millis;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
boolean changed = false;
|
||||
Iterator<Entry<String,RelayWorldsQuery>> itr = lanServersQueryList.entrySet().iterator();
|
||||
while(itr.hasNext()) {
|
||||
Entry<String,RelayWorldsQuery> etr = itr.next();
|
||||
Iterator<Entry<String, RelayWorldsQuery>> itr = lanServersQueryList.entrySet().iterator();
|
||||
while (itr.hasNext()) {
|
||||
Entry<String, RelayWorldsQuery> etr = itr.next();
|
||||
String uri = etr.getKey();
|
||||
RelayWorldsQuery q = etr.getValue();
|
||||
if(!q.isQueryOpen()) {
|
||||
if (!q.isQueryOpen()) {
|
||||
itr.remove();
|
||||
if(q.isQueryFailed()) {
|
||||
if (q.isQueryFailed()) {
|
||||
deadURIs.add(uri);
|
||||
Iterator<LanServer> itr2 = lanServersList.iterator();
|
||||
while(itr2.hasNext()) {
|
||||
if(itr2.next().lanServerRelay.address.equals(uri)) {
|
||||
while (itr2.hasNext()) {
|
||||
if (itr2.next().lanServerRelay.address.equals(uri)) {
|
||||
itr2.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
RelayServer rl = RelayManager.relayManager.getByURI(uri);
|
||||
Iterator<LanServer> itr2 = lanServersList.iterator();
|
||||
while(itr2.hasNext()) {
|
||||
while (itr2.hasNext()) {
|
||||
LanServer l = itr2.next();
|
||||
if(l.lanServerRelay.address.equals(uri)) {
|
||||
if (l.lanServerRelay.address.equals(uri)) {
|
||||
l.flagged = false;
|
||||
}
|
||||
}
|
||||
if(rl != null) {
|
||||
if (rl != null) {
|
||||
Iterator<IPacket07LocalWorlds.LocalWorld> itr3 = q.getWorlds().iterator();
|
||||
yee: while(itr3.hasNext()) {
|
||||
yee: while (itr3.hasNext()) {
|
||||
IPacket07LocalWorlds.LocalWorld l = itr3.next();
|
||||
itr2 = lanServersList.iterator();
|
||||
while(itr2.hasNext()) {
|
||||
while (itr2.hasNext()) {
|
||||
LanServer l2 = itr2.next();
|
||||
if(l2.lanServerRelay.address.equals(uri) && l2.lanServerCode.equals(l.worldCode)) {
|
||||
if (l2.lanServerRelay.address.equals(uri) && l2.lanServerCode.equals(l.worldCode)) {
|
||||
l2.lanServerMotd = l.worldName;
|
||||
l2.flagged = true;
|
||||
continue yee;
|
||||
|
@ -92,10 +100,10 @@ public class LANServerList {
|
|||
}
|
||||
}
|
||||
itr2 = lanServersList.iterator();
|
||||
while(itr2.hasNext()) {
|
||||
while (itr2.hasNext()) {
|
||||
LanServer l = itr2.next();
|
||||
if(l.lanServerRelay.address.equals(uri)) {
|
||||
if(!l.flagged) {
|
||||
if (l.lanServerRelay.address.equals(uri)) {
|
||||
if (!l.flagged) {
|
||||
itr2.remove();
|
||||
changed = true;
|
||||
}
|
||||
|
@ -108,7 +116,7 @@ public class LANServerList {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void forceRefresh() {
|
||||
deadURIs.clear();
|
||||
refreshCounter = 0;
|
||||
|
@ -117,10 +125,10 @@ public class LANServerList {
|
|||
|
||||
private void refresh() {
|
||||
lastRefresh = System.currentTimeMillis();
|
||||
if(PlatformWebRTC.supported()) {
|
||||
for(int i = 0, l = RelayManager.relayManager.count(); i < l; ++i) {
|
||||
if (PlatformWebRTC.supported()) {
|
||||
for (int i = 0, l = RelayManager.relayManager.count(); i < l; ++i) {
|
||||
RelayServer srv = RelayManager.relayManager.get(i);
|
||||
if(!lanServersQueryList.containsKey(srv.address) && !deadURIs.contains(srv.address)) {
|
||||
if (!lanServersQueryList.containsKey(srv.address) && !deadURIs.contains(srv.address)) {
|
||||
lanServersQueryList.put(srv.address, PlatformWebRTC.openRelayWorldsQuery(srv.address));
|
||||
}
|
||||
}
|
||||
|
@ -134,33 +142,33 @@ public class LANServerList {
|
|||
public int countServers() {
|
||||
return lanServersList.size();
|
||||
}
|
||||
|
||||
|
||||
public class LanServer {
|
||||
|
||||
|
||||
private String lanServerMotd;
|
||||
private RelayServer lanServerRelay;
|
||||
private String lanServerCode;
|
||||
|
||||
|
||||
protected boolean flagged = true;
|
||||
|
||||
|
||||
protected LanServer(String lanServerMotd, RelayServer lanServerRelay, String lanServerCode) {
|
||||
this.lanServerMotd = lanServerMotd;
|
||||
this.lanServerRelay = lanServerRelay;
|
||||
this.lanServerCode = lanServerCode;
|
||||
}
|
||||
|
||||
|
||||
public String getLanServerMotd() {
|
||||
return lanServerMotd;
|
||||
}
|
||||
|
||||
|
||||
public RelayServer getLanServerRelay() {
|
||||
return lanServerRelay;
|
||||
}
|
||||
|
||||
|
||||
public String getLanServerCode() {
|
||||
return lanServerCode;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +1,38 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.relay;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class RelayEntry {
|
||||
|
||||
|
||||
public final String address;
|
||||
public final String comment;
|
||||
public final boolean primary;
|
||||
|
||||
|
||||
public RelayEntry(String address, String comment, boolean primary) {
|
||||
this.address = address;
|
||||
this.comment = comment;
|
||||
this.primary = primary;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,16 +22,24 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.nbt.NBTTagList;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -42,24 +50,24 @@ public class RelayManager {
|
|||
|
||||
public static final RelayManager relayManager = new RelayManager();
|
||||
public static final int preferredRelayVersion = 1;
|
||||
|
||||
|
||||
private final List<RelayServer> relays = new ArrayList();
|
||||
private long lastPingThrough = 0l;
|
||||
|
||||
public void load(byte[] relayConfig) {
|
||||
NBTTagCompound relays = null;
|
||||
if(relayConfig != null) {
|
||||
if (relayConfig != null) {
|
||||
try {
|
||||
relays = CompressedStreamTools.readCompressed(new EaglerInputStream(relayConfig));
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if(relays != null && relays.hasKey("relays", 9)) {
|
||||
if (relays != null && relays.hasKey("relays", 9)) {
|
||||
load(relays.getTagList("relays", 10));
|
||||
if(!relays.getBoolean("f")) {
|
||||
if (!relays.getBoolean("f")) {
|
||||
fixBullshit();
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
sort(); // loads defaults
|
||||
save();
|
||||
}
|
||||
|
@ -68,14 +76,14 @@ public class RelayManager {
|
|||
// versions pre-u24 always have "relay.deev.is" as primary due to a glitch
|
||||
// this function is intended to randomize the list if that is detected
|
||||
private void fixBullshit() {
|
||||
if(!relays.isEmpty()) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if (!relays.isEmpty()) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer rs = relays.get(i);
|
||||
if(rs.address.equalsIgnoreCase("wss://relay.deev.is/") && !rs.isPrimary()) {
|
||||
if (rs.address.equalsIgnoreCase("wss://relay.deev.is/") && !rs.isPrimary()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
relays.get(i).setPrimary(false);
|
||||
}
|
||||
relays.get(ThreadLocalRandom.current().nextInt(relays.size())).setPrimary(true);
|
||||
|
@ -86,15 +94,15 @@ public class RelayManager {
|
|||
|
||||
private void load(NBTTagList relayConfig) {
|
||||
relays.clear();
|
||||
if(relayConfig != null && relayConfig.tagCount() > 0) {
|
||||
if (relayConfig != null && relayConfig.tagCount() > 0) {
|
||||
boolean gotAPrimary = false;
|
||||
for(int i = 0, l = relayConfig.tagCount(); i < l; ++i) {
|
||||
for (int i = 0, l = relayConfig.tagCount(); i < l; ++i) {
|
||||
NBTTagCompound relay = relayConfig.getCompoundTagAt(i);
|
||||
boolean p = relay.getBoolean("primary");
|
||||
if(p) {
|
||||
if(gotAPrimary) {
|
||||
if (p) {
|
||||
if (gotAPrimary) {
|
||||
p = false;
|
||||
}else {
|
||||
} else {
|
||||
gotAPrimary = true;
|
||||
}
|
||||
}
|
||||
|
@ -103,21 +111,21 @@ public class RelayManager {
|
|||
}
|
||||
sort();
|
||||
}
|
||||
|
||||
|
||||
public void save() {
|
||||
if(relays.isEmpty()) {
|
||||
if (relays.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
byte[] data = write();
|
||||
if(data != null) {
|
||||
if (data != null) {
|
||||
EagRuntime.setStorage("r", data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public byte[] write() {
|
||||
try {
|
||||
NBTTagList lst = new NBTTagList();
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer srv = relays.get(i);
|
||||
NBTTagCompound etr = new NBTTagCompound();
|
||||
etr.setString("addr", srv.address);
|
||||
|
@ -139,83 +147,83 @@ public class RelayManager {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sort() {
|
||||
if(relays.isEmpty()) {
|
||||
if (relays.isEmpty()) {
|
||||
List<RelayEntry> defaultRelays = EagRuntime.getConfiguration().getRelays();
|
||||
for(int i = 0, l = defaultRelays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = defaultRelays.size(); i < l; ++i) {
|
||||
relays.add(new RelayServer(defaultRelays.get(i)));
|
||||
}
|
||||
}
|
||||
if(relays.isEmpty()) {
|
||||
if (relays.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int j = -1;
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if(relays.get(i).isPrimary()) {
|
||||
if(j == -1) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if (relays.get(i).isPrimary()) {
|
||||
if (j == -1) {
|
||||
j = i;
|
||||
}else {
|
||||
} else {
|
||||
relays.get(i).setPrimary(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(j == -1) {
|
||||
if (j == -1) {
|
||||
boolean found = false;
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer srv = relays.get(i);
|
||||
if(srv.getPing() > 0l) {
|
||||
if (srv.getPing() > 0l) {
|
||||
found = true;
|
||||
srv.setPrimary(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
if (!found) {
|
||||
relays.get(0).setPrimary(true);
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
RelayServer srv = relays.remove(j);
|
||||
relays.add(0, srv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ping() {
|
||||
lastPingThrough = System.currentTimeMillis();
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
relays.get(i).ping();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void update() {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
relays.get(i).update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
relays.get(i).close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int count() {
|
||||
return relays.size();
|
||||
}
|
||||
|
||||
|
||||
public RelayServer get(int idx) {
|
||||
return relays.get(idx);
|
||||
}
|
||||
|
||||
|
||||
public void add(String addr, String comment, boolean primary) {
|
||||
lastPingThrough = 0l;
|
||||
int i = relays.size();
|
||||
relays.add(new RelayServer(addr, comment, false));
|
||||
if(primary) {
|
||||
if (primary) {
|
||||
setPrimary0(i);
|
||||
}
|
||||
save();
|
||||
}
|
||||
|
||||
|
||||
public void addNew(String addr, String comment, boolean primary) {
|
||||
lastPingThrough = 0l;
|
||||
int i = relays.size();
|
||||
|
@ -223,22 +231,22 @@ public class RelayManager {
|
|||
RelayServer newServer = new RelayServer(addr, comment, false);
|
||||
relays.add(j, newServer);
|
||||
newServer.ping();
|
||||
if(primary) {
|
||||
if (primary) {
|
||||
setPrimary0(j);
|
||||
}
|
||||
save();
|
||||
}
|
||||
|
||||
|
||||
public void setPrimary(int idx) {
|
||||
setPrimary0(idx);
|
||||
save();
|
||||
}
|
||||
|
||||
private void setPrimary0(int idx) {
|
||||
if(idx >= 0 && idx < relays.size()) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if (idx >= 0 && idx < relays.size()) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer srv = relays.get(i);
|
||||
if(srv.isPrimary()) {
|
||||
if (srv.isPrimary()) {
|
||||
srv.setPrimary(false);
|
||||
}
|
||||
}
|
||||
|
@ -247,51 +255,53 @@ public class RelayManager {
|
|||
relays.add(0, pr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void remove(int idx) {
|
||||
RelayServer srv = relays.remove(idx);
|
||||
srv.close();
|
||||
sort();
|
||||
save();
|
||||
}
|
||||
|
||||
|
||||
public RelayServer getPrimary() {
|
||||
if(!relays.isEmpty()) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if (!relays.isEmpty()) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer srv = relays.get(i);
|
||||
if(srv.isPrimary()) {
|
||||
if (srv.isPrimary()) {
|
||||
return srv;
|
||||
}
|
||||
}
|
||||
sort();
|
||||
save();
|
||||
return getPrimary();
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RelayServerSocket connectHandshake(RelayServer relay, int type, String code) {
|
||||
RelayServerSocket sock = relay.openSocket();
|
||||
while(!sock.isClosed()) {
|
||||
if(sock.isOpen()) {
|
||||
while (!sock.isClosed()) {
|
||||
if (sock.isOpen()) {
|
||||
sock.writePacket(new IPacket00Handshake(type, preferredRelayVersion, code));
|
||||
while(!sock.isClosed()) {
|
||||
while (!sock.isClosed()) {
|
||||
IPacket pkt = sock.nextPacket();
|
||||
if(pkt != null) {
|
||||
if(pkt instanceof IPacket00Handshake) {
|
||||
if (pkt != null) {
|
||||
if (pkt instanceof IPacket00Handshake) {
|
||||
return sock;
|
||||
}else if(pkt instanceof IPacketFFErrorCode) {
|
||||
} else if (pkt instanceof IPacketFFErrorCode) {
|
||||
IPacketFFErrorCode ipkt = (IPacketFFErrorCode) pkt;
|
||||
logger.error("Relay [{}] failed: {}({}): {}", relay.address, IPacketFFErrorCode.code2string(ipkt.code), ipkt.code, ipkt.desc);
|
||||
logger.error("Relay [{}] failed: {}({}): {}", relay.address,
|
||||
IPacketFFErrorCode.code2string(ipkt.code), ipkt.code, ipkt.desc);
|
||||
Throwable t;
|
||||
while((t = sock.getException()) != null) {
|
||||
while ((t = sock.getException()) != null) {
|
||||
logger.error(t);
|
||||
}
|
||||
sock.close();
|
||||
return null;
|
||||
}else {
|
||||
logger.error("Relay [{}] unexpected packet: {}", relay.address, pkt.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("Relay [{}] unexpected packet: {}", relay.address,
|
||||
pkt.getClass().getSimpleName());
|
||||
sock.close();
|
||||
return null;
|
||||
}
|
||||
|
@ -303,42 +313,42 @@ public class RelayManager {
|
|||
}
|
||||
logger.error("Relay [{}] connection failed!", relay.address);
|
||||
Throwable t;
|
||||
while((t = sock.getException()) != null) {
|
||||
while ((t = sock.getException()) != null) {
|
||||
logger.error(t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private final List<RelayServer> brokenServers = new LinkedList();
|
||||
|
||||
public RelayServerSocket getWorkingRelay(Consumer<String> progressCallback, int type, String code) {
|
||||
brokenServers.clear();
|
||||
if(!relays.isEmpty()) {
|
||||
if (!relays.isEmpty()) {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastPingThrough < 10000l) {
|
||||
if (millis - lastPingThrough < 10000l) {
|
||||
RelayServer relay = getPrimary();
|
||||
if(relay.getPing() > 0l && relay.getPingCompatible().isCompatible()) {
|
||||
if (relay.getPing() > 0l && relay.getPingCompatible().isCompatible()) {
|
||||
progressCallback.accept(relay.address);
|
||||
RelayServerSocket sock = connectHandshake(relay, type, code);
|
||||
if(sock != null) {
|
||||
if(!sock.isFailed()) {
|
||||
if (sock != null) {
|
||||
if (!sock.isFailed()) {
|
||||
return sock;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
brokenServers.add(relay);
|
||||
}
|
||||
}
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer relayEtr = relays.get(i);
|
||||
if(relayEtr != relay) {
|
||||
if(relayEtr.getPing() > 0l && relayEtr.getPingCompatible().isCompatible()) {
|
||||
if (relayEtr != relay) {
|
||||
if (relayEtr.getPing() > 0l && relayEtr.getPingCompatible().isCompatible()) {
|
||||
progressCallback.accept(relayEtr.address);
|
||||
RelayServerSocket sock = connectHandshake(relayEtr, type, code);
|
||||
if(sock != null) {
|
||||
if(!sock.isFailed()) {
|
||||
if (sock != null) {
|
||||
if (!sock.isFailed()) {
|
||||
return sock;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
brokenServers.add(relayEtr);
|
||||
}
|
||||
}
|
||||
|
@ -346,39 +356,39 @@ public class RelayManager {
|
|||
}
|
||||
}
|
||||
return getWorkingCodeRelayActive(progressCallback, type, code);
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private RelayServerSocket getWorkingCodeRelayActive(Consumer<String> progressCallback, int type, String code) {
|
||||
if(!relays.isEmpty()) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if (!relays.isEmpty()) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayServer srv = relays.get(i);
|
||||
if(!brokenServers.contains(srv)) {
|
||||
if (!brokenServers.contains(srv)) {
|
||||
progressCallback.accept(srv.address);
|
||||
RelayServerSocket sock = connectHandshake(srv, type, code);
|
||||
if(sock != null) {
|
||||
if(!sock.isFailed()) {
|
||||
if (sock != null) {
|
||||
if (!sock.isFailed()) {
|
||||
return sock;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
brokenServers.add(srv);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void loadDefaults() {
|
||||
List<RelayEntry> defaultRelays = EagRuntime.getConfiguration().getRelays();
|
||||
eee: for(int i = 0, l = defaultRelays.size(); i < l; ++i) {
|
||||
eee: for (int i = 0, l = defaultRelays.size(); i < l; ++i) {
|
||||
RelayEntry etr = defaultRelays.get(i);
|
||||
for(int j = 0, l2 = relays.size(); j < l2; ++j) {
|
||||
if(relays.get(j).address.equalsIgnoreCase(etr.address)) {
|
||||
for (int j = 0, l2 = relays.size(); j < l2; ++j) {
|
||||
if (relays.get(j).address.equalsIgnoreCase(etr.address)) {
|
||||
continue eee;
|
||||
}
|
||||
}
|
||||
|
@ -386,17 +396,17 @@ public class RelayManager {
|
|||
}
|
||||
sort();
|
||||
}
|
||||
|
||||
|
||||
public String makeNewRelayName() {
|
||||
String str = "Relay Server #" + (relays.size() + 1);
|
||||
for(int i = relays.size() + 2, l = relays.size() + 50; i < l; ++i) {
|
||||
if(str.equalsIgnoreCase("Relay Server #" + i)) {
|
||||
for (int i = relays.size() + 2, l = relays.size() + 50; i < l; ++i) {
|
||||
if (str.equalsIgnoreCase("Relay Server #" + i)) {
|
||||
str = "Relay Server #" + (i + 1);
|
||||
}
|
||||
}
|
||||
eee: while(true) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if(str.equalsIgnoreCase(relays.get(i).comment)) {
|
||||
eee: while (true) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
if (str.equalsIgnoreCase(relays.get(i).comment)) {
|
||||
str = str + "_";
|
||||
continue eee;
|
||||
}
|
||||
|
@ -405,16 +415,16 @@ public class RelayManager {
|
|||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
public RelayServer getByURI(String uri) {
|
||||
Iterator<RelayServer> itr = relays.iterator();
|
||||
while(itr.hasNext()) {
|
||||
while (itr.hasNext()) {
|
||||
RelayServer rl = itr.next();
|
||||
if(rl.address.equals(uri)) {
|
||||
if (rl.address.equals(uri)) {
|
||||
return rl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.relay;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -23,19 +31,26 @@ public interface RelayQuery {
|
|||
|
||||
enum VersionMismatch {
|
||||
COMPATIBLE, CLIENT_OUTDATED, RELAY_OUTDATED, UNKNOWN;
|
||||
|
||||
public boolean isCompatible() {
|
||||
return this == COMPATIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isQueryOpen();
|
||||
|
||||
boolean isQueryFailed();
|
||||
|
||||
RateLimit isQueryRateLimit();
|
||||
|
||||
void close();
|
||||
|
||||
|
||||
int getVersion();
|
||||
|
||||
String getComment();
|
||||
|
||||
String getBrand();
|
||||
|
||||
long getPing();
|
||||
|
||||
VersionMismatch getCompatible();
|
||||
|
|
|
@ -6,26 +6,34 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayQuery.VersionMismatch;
|
|||
import net.minecraft.client.Minecraft;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class RelayServer {
|
||||
|
||||
|
||||
public final String address;
|
||||
public final String comment;
|
||||
private boolean primary;
|
||||
|
||||
|
||||
private RelayQuery query = null;
|
||||
private int queriedVersion = -1;
|
||||
private String queriedComment;
|
||||
|
@ -40,15 +48,15 @@ public class RelayServer {
|
|||
this.comment = comment;
|
||||
this.primary = primary;
|
||||
}
|
||||
|
||||
|
||||
public RelayServer(RelayEntry etr) {
|
||||
this(etr.address, etr.comment, etr.primary);
|
||||
}
|
||||
|
||||
|
||||
public boolean isPrimary() {
|
||||
return primary;
|
||||
}
|
||||
|
||||
|
||||
public void setPrimary(boolean primaryee) {
|
||||
primary = primaryee;
|
||||
}
|
||||
|
@ -60,33 +68,33 @@ public class RelayServer {
|
|||
public long getWorkingPing() {
|
||||
return workingPing;
|
||||
}
|
||||
|
||||
|
||||
public int getPingVersion() {
|
||||
return queriedVersion;
|
||||
}
|
||||
|
||||
|
||||
public String getPingComment() {
|
||||
return queriedComment == null ? "" : queriedComment;
|
||||
}
|
||||
|
||||
|
||||
public String getPingVendor() {
|
||||
return queriedVendor == null ? "" : queriedVendor;
|
||||
}
|
||||
|
||||
|
||||
public VersionMismatch getPingCompatible() {
|
||||
return queriedCompatible;
|
||||
}
|
||||
|
||||
|
||||
public void pingBlocking() {
|
||||
ping();
|
||||
while(getPing() < 0l) {
|
||||
while (getPing() < 0l) {
|
||||
EagUtils.sleep(250l);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ping() {
|
||||
if(PlatformWebRTC.supported()) {
|
||||
if (PlatformWebRTC.supported()) {
|
||||
close();
|
||||
query = PlatformWebRTC.openRelayQuery(address);
|
||||
queriedVersion = -1;
|
||||
|
@ -94,7 +102,7 @@ public class RelayServer {
|
|||
queriedVendor = null;
|
||||
queriedCompatible = VersionMismatch.UNKNOWN;
|
||||
ping = -1l;
|
||||
}else {
|
||||
} else {
|
||||
query = null;
|
||||
queriedVersion = 1;
|
||||
queriedComment = "LAN NOT SUPPORTED";
|
||||
|
@ -103,16 +111,16 @@ public class RelayServer {
|
|||
ping = -1l;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void update() {
|
||||
if(query != null && !query.isQueryOpen()) {
|
||||
if(query.isQueryFailed()) {
|
||||
if (query != null && !query.isQueryOpen()) {
|
||||
if (query.isQueryFailed()) {
|
||||
queriedVersion = -1;
|
||||
queriedComment = null;
|
||||
queriedVendor = null;
|
||||
queriedCompatible = VersionMismatch.UNKNOWN;
|
||||
ping = 0l;
|
||||
}else {
|
||||
} else {
|
||||
queriedVersion = query.getVersion();
|
||||
queriedComment = query.getComment();
|
||||
queriedVendor = query.getBrand();
|
||||
|
@ -124,9 +132,9 @@ public class RelayServer {
|
|||
query = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
if(query != null && query.isQueryOpen()) {
|
||||
if (query != null && query.isQueryOpen()) {
|
||||
query.close();
|
||||
query = null;
|
||||
queriedVersion = -1;
|
||||
|
@ -136,9 +144,9 @@ public class RelayServer {
|
|||
ping = 0l;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RelayServerSocket openSocket() {
|
||||
return PlatformWebRTC.openRelayConnection(address, Minecraft.getMinecraft().gameSettings.relayTimeout * 1000);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,16 +3,24 @@ package net.lax1dude.eaglercraft.v1_8.sp.relay;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -20,19 +28,23 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket;
|
|||
public interface RelayServerSocket {
|
||||
|
||||
boolean isOpen();
|
||||
|
||||
boolean isClosed();
|
||||
|
||||
void close();
|
||||
|
||||
|
||||
boolean isFailed();
|
||||
|
||||
Throwable getException();
|
||||
|
||||
|
||||
void writePacket(IPacket pkt);
|
||||
|
||||
|
||||
IPacket readPacket();
|
||||
|
||||
IPacket nextPacket();
|
||||
|
||||
|
||||
RelayQuery.RateLimit getRatelimitHistory();
|
||||
|
||||
|
||||
String getURI();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,16 +6,24 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayQuery.VersionMismatch;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket07LocalWorlds;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -23,12 +31,15 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.IPacket07LocalWorlds;
|
|||
public interface RelayWorldsQuery {
|
||||
|
||||
boolean isQueryOpen();
|
||||
|
||||
boolean isQueryFailed();
|
||||
|
||||
RelayQuery.RateLimit isQueryRateLimit();
|
||||
|
||||
void close();
|
||||
|
||||
|
||||
List<IPacket07LocalWorlds.LocalWorld> getWorlds();
|
||||
|
||||
|
||||
VersionMismatch getCompatible();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -35,16 +35,24 @@ import net.minecraft.nbt.CompressedStreamTools;
|
|||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -62,23 +70,23 @@ public class EaglerIntegratedServerWorker {
|
|||
|
||||
private static void processAsyncMessageQueue() {
|
||||
List<IPCPacketData> pktList = ServerPlatformSingleplayer.recieveAllPacket();
|
||||
if(pktList != null) {
|
||||
if (pktList != null) {
|
||||
IPCPacketData packetData;
|
||||
for(int i = 0, l = pktList.size(); i < l; ++i) {
|
||||
for (int i = 0, l = pktList.size(); i < l; ++i) {
|
||||
packetData = pktList.get(i);
|
||||
if(packetData.channel.equals(SingleplayerServerController.IPC_CHANNEL)) {
|
||||
if (packetData.channel.equals(SingleplayerServerController.IPC_CHANNEL)) {
|
||||
IPCPacketBase ipc;
|
||||
try {
|
||||
ipc = IPCPacketManager.IPCDeserialize(packetData.contents);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to deserialize IPC packet", ex);
|
||||
}
|
||||
handleIPCPacket(ipc);
|
||||
}else {
|
||||
} else {
|
||||
IntegratedServerPlayerNetworkManager netHandler = openChannels.get(packetData.channel);
|
||||
if(netHandler != null) {
|
||||
if (netHandler != null) {
|
||||
netHandler.addRecievedPacket(packetData.contents);
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Recieved packet on channel that does not exist: \"{}\"", packetData.channel);
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +96,7 @@ public class EaglerIntegratedServerWorker {
|
|||
|
||||
public static void tick() {
|
||||
List<IntegratedServerPlayerNetworkManager> ocs = new ArrayList<>(openChannels.values());
|
||||
for(int i = 0, l = ocs.size(); i < l; ++i) {
|
||||
for (int i = 0, l = ocs.size(); i < l; ++i) {
|
||||
ocs.get(i).tick();
|
||||
}
|
||||
}
|
||||
|
@ -103,18 +111,18 @@ public class EaglerIntegratedServerWorker {
|
|||
|
||||
public static void closeChannel(String channel) {
|
||||
IntegratedServerPlayerNetworkManager netmanager = openChannels.remove(channel);
|
||||
if(netmanager != null) {
|
||||
if (netmanager != null) {
|
||||
netmanager.closeChannel(new ChatComponentText("End of stream"));
|
||||
sendIPCPacket(new IPCPacket0CPlayerChannel(channel, false));
|
||||
}
|
||||
}
|
||||
|
||||
private static void startPlayerConnnection(String channel) {
|
||||
if(openChannels.containsKey(channel)) {
|
||||
if (openChannels.containsKey(channel)) {
|
||||
logger.error("Tried opening player channel that already exists: {}", channel);
|
||||
return;
|
||||
}
|
||||
if(currentProcess == null) {
|
||||
if (currentProcess == null) {
|
||||
logger.error("Tried opening player channel while server is stopped: {}", channel);
|
||||
return;
|
||||
}
|
||||
|
@ -127,281 +135,295 @@ public class EaglerIntegratedServerWorker {
|
|||
private static void handleIPCPacket(IPCPacketBase ipc) {
|
||||
int id = ipc.id();
|
||||
try {
|
||||
switch(id) {
|
||||
case IPCPacket00StartServer.ID: {
|
||||
IPCPacket00StartServer pkt = (IPCPacket00StartServer)ipc;
|
||||
|
||||
if(!isServerStopped()) {
|
||||
currentProcess.stopServer();
|
||||
}
|
||||
|
||||
currentProcess = new EaglerMinecraftServer(pkt.worldName, pkt.ownerName, pkt.initialViewDistance, newWorldSettings, pkt.demoMode);
|
||||
currentProcess.setBaseServerProperties(EnumDifficulty.getDifficultyEnum(pkt.initialDifficulty), newWorldSettings == null ? GameType.SURVIVAL : newWorldSettings.getGameType());
|
||||
currentProcess.startServer();
|
||||
|
||||
String[] worlds = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if(worlds == null || (worlds.length == 1 && worlds[0].trim().length() <= 0)) {
|
||||
worlds = null;
|
||||
}
|
||||
if(worlds == null) {
|
||||
EaglerSaveFormat.worldsList.setAllChars(pkt.worldName);
|
||||
}else {
|
||||
boolean found = false;
|
||||
for(int i = 0; i < worlds.length; ++i) {
|
||||
if(worlds[i].equals(pkt.worldName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
switch (id) {
|
||||
case IPCPacket00StartServer.ID: {
|
||||
IPCPacket00StartServer pkt = (IPCPacket00StartServer) ipc;
|
||||
|
||||
if (!isServerStopped()) {
|
||||
currentProcess.stopServer();
|
||||
}
|
||||
if(!found) {
|
||||
String[] s = new String[worlds.length + 1];
|
||||
s[0] = pkt.worldName;
|
||||
System.arraycopy(worlds, 0, s, 1, worlds.length);
|
||||
EaglerSaveFormat.worldsList.setAllChars(String.join("\n", s));
|
||||
}
|
||||
}
|
||||
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket00StartServer.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket01StopServer.ID: {
|
||||
if(currentProcess != null) {
|
||||
currentProcess.stopServer();
|
||||
currentProcess = null;
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket01StopServer.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket02InitWorld.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket02InitWorld pkt = (IPCPacket02InitWorld)ipc;
|
||||
newWorldSettings = new WorldSettings(pkt.seed, GameType.getByID(pkt.gamemode), pkt.structures,
|
||||
pkt.hardcore, WorldType.worldTypes[pkt.worldType]);
|
||||
newWorldSettings.setWorldName(pkt.worldArgs); // "setWorldName" is actually for setting generator arguments, MCP fucked up
|
||||
if(pkt.bonusChest) {
|
||||
newWorldSettings.enableBonusChest();
|
||||
}
|
||||
if(pkt.cheats) {
|
||||
newWorldSettings.enableCommands();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket03DeleteWorld.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket03DeleteWorld pkt = (IPCPacket03DeleteWorld)ipc;
|
||||
if(!saveFormat.deleteWorldDirectory(pkt.worldName)) {
|
||||
sendTaskFailed();
|
||||
break;
|
||||
}
|
||||
String[] worldsTxt = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if(worldsTxt != null) {
|
||||
List<String> newWorlds = new ArrayList();
|
||||
for(int i = 0; i < worldsTxt.length; ++i) {
|
||||
String str = worldsTxt[i];
|
||||
if(!str.equalsIgnoreCase(pkt.worldName)) {
|
||||
newWorlds.add(str);
|
||||
}
|
||||
}
|
||||
EaglerSaveFormat.worldsList.setAllChars(String.join("\n", newWorlds));
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket03DeleteWorld.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket05RequestData.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket05RequestData pkt = (IPCPacket05RequestData)ipc;
|
||||
if(pkt.request == IPCPacket05RequestData.REQUEST_LEVEL_EAG) {
|
||||
sendIPCPacket(new IPCPacket09RequestResponse(WorldConverterEPK.exportWorld(pkt.worldName)));
|
||||
}else if(pkt.request == IPCPacket05RequestData.REQUEST_LEVEL_MCA) {
|
||||
sendIPCPacket(new IPCPacket09RequestResponse(WorldConverterMCA.exportWorld(pkt.worldName)));
|
||||
}else {
|
||||
logger.error("Unknown IPCPacket05RequestData type {}", ((int)pkt.request & 0xFF));
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket06RenameWorldNBT.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket06RenameWorldNBT pkt = (IPCPacket06RenameWorldNBT)ipc;
|
||||
boolean b = false;
|
||||
if(pkt.duplicate) {
|
||||
b = saveFormat.duplicateWorld(pkt.worldName, pkt.displayName);
|
||||
}else {
|
||||
b = saveFormat.renameWorld(pkt.worldName, pkt.displayName);
|
||||
}
|
||||
if(!b) {
|
||||
sendTaskFailed();
|
||||
break;
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket06RenameWorldNBT.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket07ImportWorld.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket07ImportWorld pkt = (IPCPacket07ImportWorld)ipc;
|
||||
try {
|
||||
if(pkt.worldFormat == IPCPacket07ImportWorld.WORLD_FORMAT_EAG) {
|
||||
WorldConverterEPK.importWorld(pkt.worldData, pkt.worldName);
|
||||
}else if(pkt.worldFormat == IPCPacket07ImportWorld.WORLD_FORMAT_MCA) {
|
||||
WorldConverterMCA.importWorld(pkt.worldData, pkt.worldName, pkt.gameRules);
|
||||
}else {
|
||||
throw new IOException("Client requested an unsupported export format!");
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket07ImportWorld.ID));
|
||||
}catch(IOException ex) {
|
||||
sendIPCPacket(new IPCPacket15Crashed("COULD NOT IMPORT WORLD \"" + pkt.worldName + "\"!!!\n\n" + EagRuntime.getStackTrace(ex) + "\n\nFile is probably corrupt, try a different world"));
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0ASetWorldDifficulty.ID: {
|
||||
IPCPacket0ASetWorldDifficulty pkt = (IPCPacket0ASetWorldDifficulty)ipc;
|
||||
if(!isServerStopped()) {
|
||||
if(pkt.difficulty == (byte)-1) {
|
||||
currentProcess.setDifficultyLockedForAllWorlds(true);
|
||||
}else {
|
||||
currentProcess.setDifficultyForAllWorlds(EnumDifficulty.getDifficultyEnum(pkt.difficulty));
|
||||
}
|
||||
}else {
|
||||
logger.warn("Client tried to set difficulty while server was stopped");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0BPause.ID: {
|
||||
IPCPacket0BPause pkt = (IPCPacket0BPause)ipc;
|
||||
if(!isServerStopped()) {
|
||||
currentProcess.setPaused(pkt.pause);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket0BPause.ID));
|
||||
}else {
|
||||
logger.error("Client tried to {} while server was stopped", pkt.pause ? "pause" : "unpause");
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0CPlayerChannel.ID: {
|
||||
IPCPacket0CPlayerChannel pkt = (IPCPacket0CPlayerChannel)ipc;
|
||||
if(!isServerStopped()) {
|
||||
if(pkt.open) {
|
||||
startPlayerConnnection(pkt.channel);
|
||||
}else {
|
||||
closeChannel(pkt.channel);
|
||||
}
|
||||
}else {
|
||||
logger.error("Client tried to {} channel server was stopped", pkt.open ? "open" : "close");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0EListWorlds.ID: {
|
||||
IPCPacket0EListWorlds pkt = (IPCPacket0EListWorlds)ipc;
|
||||
if(!isServerStopped()) {
|
||||
logger.error("Client tried to list worlds while server was running");
|
||||
sendTaskFailed();
|
||||
}else {
|
||||
|
||||
currentProcess = new EaglerMinecraftServer(pkt.worldName, pkt.ownerName, pkt.initialViewDistance,
|
||||
newWorldSettings, pkt.demoMode);
|
||||
currentProcess.setBaseServerProperties(EnumDifficulty.getDifficultyEnum(pkt.initialDifficulty),
|
||||
newWorldSettings == null ? GameType.SURVIVAL : newWorldSettings.getGameType());
|
||||
currentProcess.startServer();
|
||||
|
||||
String[] worlds = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if(worlds == null) {
|
||||
sendIPCPacket(new IPCPacket16NBTList(IPCPacket16NBTList.WORLD_LIST, new LinkedList<NBTTagCompound>()));
|
||||
if (worlds == null || (worlds.length == 1 && worlds[0].trim().length() <= 0)) {
|
||||
worlds = null;
|
||||
}
|
||||
if (worlds == null) {
|
||||
EaglerSaveFormat.worldsList.setAllChars(pkt.worldName);
|
||||
} else {
|
||||
boolean found = false;
|
||||
for (int i = 0; i < worlds.length; ++i) {
|
||||
if (worlds[i].equals(pkt.worldName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
String[] s = new String[worlds.length + 1];
|
||||
s[0] = pkt.worldName;
|
||||
System.arraycopy(worlds, 0, s, 1, worlds.length);
|
||||
EaglerSaveFormat.worldsList.setAllChars(String.join("\n", s));
|
||||
}
|
||||
}
|
||||
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket00StartServer.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket01StopServer.ID: {
|
||||
if (currentProcess != null) {
|
||||
currentProcess.stopServer();
|
||||
currentProcess = null;
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket01StopServer.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket02InitWorld.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket02InitWorld pkt = (IPCPacket02InitWorld) ipc;
|
||||
newWorldSettings = new WorldSettings(pkt.seed, GameType.getByID(pkt.gamemode), pkt.structures,
|
||||
pkt.hardcore, WorldType.worldTypes[pkt.worldType]);
|
||||
newWorldSettings.setWorldName(pkt.worldArgs); // "setWorldName" is actually for setting generator
|
||||
// arguments, MCP fucked up
|
||||
if (pkt.bonusChest) {
|
||||
newWorldSettings.enableBonusChest();
|
||||
}
|
||||
if (pkt.cheats) {
|
||||
newWorldSettings.enableCommands();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket03DeleteWorld.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket03DeleteWorld pkt = (IPCPacket03DeleteWorld) ipc;
|
||||
if (!saveFormat.deleteWorldDirectory(pkt.worldName)) {
|
||||
sendTaskFailed();
|
||||
break;
|
||||
}
|
||||
LinkedHashSet<String> updatedList = new LinkedHashSet();
|
||||
LinkedList<NBTTagCompound> sendListNBT = new LinkedList();
|
||||
boolean rewrite = false;
|
||||
for(int i = 0; i < worlds.length; ++i) {
|
||||
String w = worlds[i].trim();
|
||||
if(w.length() > 0) {
|
||||
VFile2 vf = new VFile2(EaglerSaveFormat.worldsFolder, w, "level.dat");
|
||||
if(!vf.exists()) {
|
||||
vf = new VFile2(EaglerSaveFormat.worldsFolder, w, "level.dat_old");
|
||||
String[] worldsTxt = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if (worldsTxt != null) {
|
||||
List<String> newWorlds = new ArrayList();
|
||||
for (int i = 0; i < worldsTxt.length; ++i) {
|
||||
String str = worldsTxt[i];
|
||||
if (!str.equalsIgnoreCase(pkt.worldName)) {
|
||||
newWorlds.add(str);
|
||||
}
|
||||
if(vf.exists()) {
|
||||
try(InputStream dat = vf.getInputStream()) {
|
||||
if(updatedList.add(w)) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(dat);
|
||||
worldDatNBT.setString("folderNameEagler", w);
|
||||
sendListNBT.add(worldDatNBT);
|
||||
}else {
|
||||
rewrite = true;
|
||||
}
|
||||
continue;
|
||||
}catch(IOException e) {
|
||||
// shit fuck
|
||||
}
|
||||
}
|
||||
rewrite = true;
|
||||
logger.error("World level.dat for '{}' was not found, attempting to delete", w);
|
||||
if(!saveFormat.deleteWorldDirectory(w)) {
|
||||
logger.error("Failed to delete '{}'! It will be removed from the worlds list anyway", w);
|
||||
}
|
||||
}else {
|
||||
rewrite = true;
|
||||
}
|
||||
EaglerSaveFormat.worldsList.setAllChars(String.join("\n", newWorlds));
|
||||
}
|
||||
if(rewrite) {
|
||||
EaglerSaveFormat.worldsList.setAllChars(String.join("\n", updatedList));
|
||||
}
|
||||
sendIPCPacket(new IPCPacket16NBTList(IPCPacket16NBTList.WORLD_LIST, sendListNBT));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket14StringList.ID: {
|
||||
IPCPacket14StringList pkt = (IPCPacket14StringList)ipc;
|
||||
switch(pkt.opCode) {
|
||||
case IPCPacket14StringList.LOCALE:
|
||||
StringTranslate.initServer(pkt.stringList);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket03DeleteWorld.ID));
|
||||
break;
|
||||
//case IPCPacket14StringList.STAT_GUID:
|
||||
// AchievementMap.init(pkt.stringList);
|
||||
// AchievementList.init();
|
||||
// break;
|
||||
}
|
||||
case IPCPacket05RequestData.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket05RequestData pkt = (IPCPacket05RequestData) ipc;
|
||||
if (pkt.request == IPCPacket05RequestData.REQUEST_LEVEL_EAG) {
|
||||
sendIPCPacket(new IPCPacket09RequestResponse(WorldConverterEPK.exportWorld(pkt.worldName)));
|
||||
} else if (pkt.request == IPCPacket05RequestData.REQUEST_LEVEL_MCA) {
|
||||
sendIPCPacket(new IPCPacket09RequestResponse(WorldConverterMCA.exportWorld(pkt.worldName)));
|
||||
} else {
|
||||
logger.error("Unknown IPCPacket05RequestData type {}", ((int) pkt.request & 0xFF));
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket06RenameWorldNBT.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket06RenameWorldNBT pkt = (IPCPacket06RenameWorldNBT) ipc;
|
||||
boolean b = false;
|
||||
if (pkt.duplicate) {
|
||||
b = saveFormat.duplicateWorld(pkt.worldName, pkt.displayName);
|
||||
} else {
|
||||
b = saveFormat.renameWorld(pkt.worldName, pkt.displayName);
|
||||
}
|
||||
if (!b) {
|
||||
sendTaskFailed();
|
||||
break;
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket06RenameWorldNBT.ID));
|
||||
break;
|
||||
}
|
||||
case IPCPacket07ImportWorld.ID: {
|
||||
tryStopServer();
|
||||
IPCPacket07ImportWorld pkt = (IPCPacket07ImportWorld) ipc;
|
||||
try {
|
||||
if (pkt.worldFormat == IPCPacket07ImportWorld.WORLD_FORMAT_EAG) {
|
||||
WorldConverterEPK.importWorld(pkt.worldData, pkt.worldName);
|
||||
} else if (pkt.worldFormat == IPCPacket07ImportWorld.WORLD_FORMAT_MCA) {
|
||||
WorldConverterMCA.importWorld(pkt.worldData, pkt.worldName, pkt.gameRules);
|
||||
} else {
|
||||
throw new IOException("Client requested an unsupported export format!");
|
||||
}
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket07ImportWorld.ID));
|
||||
} catch (IOException ex) {
|
||||
sendIPCPacket(new IPCPacket15Crashed(
|
||||
"COULD NOT IMPORT WORLD \"" + pkt.worldName + "\"!!!\n\n" + EagRuntime.getStackTrace(ex)
|
||||
+ "\n\nFile is probably corrupt, try a different world"));
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0ASetWorldDifficulty.ID: {
|
||||
IPCPacket0ASetWorldDifficulty pkt = (IPCPacket0ASetWorldDifficulty) ipc;
|
||||
if (!isServerStopped()) {
|
||||
if (pkt.difficulty == (byte) -1) {
|
||||
currentProcess.setDifficultyLockedForAllWorlds(true);
|
||||
} else {
|
||||
currentProcess.setDifficultyForAllWorlds(EnumDifficulty.getDifficultyEnum(pkt.difficulty));
|
||||
}
|
||||
} else {
|
||||
logger.warn("Client tried to set difficulty while server was stopped");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0BPause.ID: {
|
||||
IPCPacket0BPause pkt = (IPCPacket0BPause) ipc;
|
||||
if (!isServerStopped()) {
|
||||
currentProcess.setPaused(pkt.pause);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket0BPause.ID));
|
||||
} else {
|
||||
logger.error("Client tried to {} while server was stopped", pkt.pause ? "pause" : "unpause");
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0CPlayerChannel.ID: {
|
||||
IPCPacket0CPlayerChannel pkt = (IPCPacket0CPlayerChannel) ipc;
|
||||
if (!isServerStopped()) {
|
||||
if (pkt.open) {
|
||||
startPlayerConnnection(pkt.channel);
|
||||
} else {
|
||||
closeChannel(pkt.channel);
|
||||
}
|
||||
} else {
|
||||
logger.error("Client tried to {} channel server was stopped", pkt.open ? "open" : "close");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket0EListWorlds.ID: {
|
||||
IPCPacket0EListWorlds pkt = (IPCPacket0EListWorlds) ipc;
|
||||
if (!isServerStopped()) {
|
||||
logger.error("Client tried to list worlds while server was running");
|
||||
sendTaskFailed();
|
||||
} else {
|
||||
String[] worlds = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if (worlds == null) {
|
||||
sendIPCPacket(new IPCPacket16NBTList(IPCPacket16NBTList.WORLD_LIST,
|
||||
new LinkedList<NBTTagCompound>()));
|
||||
break;
|
||||
}
|
||||
LinkedHashSet<String> updatedList = new LinkedHashSet();
|
||||
LinkedList<NBTTagCompound> sendListNBT = new LinkedList();
|
||||
boolean rewrite = false;
|
||||
for (int i = 0; i < worlds.length; ++i) {
|
||||
String w = worlds[i].trim();
|
||||
if (w.length() > 0) {
|
||||
VFile2 vf = new VFile2(EaglerSaveFormat.worldsFolder, w, "level.dat");
|
||||
if (!vf.exists()) {
|
||||
vf = new VFile2(EaglerSaveFormat.worldsFolder, w, "level.dat_old");
|
||||
}
|
||||
if (vf.exists()) {
|
||||
try (InputStream dat = vf.getInputStream()) {
|
||||
if (updatedList.add(w)) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(dat);
|
||||
worldDatNBT.setString("folderNameEagler", w);
|
||||
sendListNBT.add(worldDatNBT);
|
||||
} else {
|
||||
rewrite = true;
|
||||
}
|
||||
continue;
|
||||
} catch (IOException e) {
|
||||
// shit fuck
|
||||
}
|
||||
}
|
||||
rewrite = true;
|
||||
logger.error("World level.dat for '{}' was not found, attempting to delete", w);
|
||||
if (!saveFormat.deleteWorldDirectory(w)) {
|
||||
logger.error(
|
||||
"Failed to delete '{}'! It will be removed from the worlds list anyway", w);
|
||||
}
|
||||
} else {
|
||||
rewrite = true;
|
||||
}
|
||||
}
|
||||
if (rewrite) {
|
||||
EaglerSaveFormat.worldsList.setAllChars(String.join("\n", updatedList));
|
||||
}
|
||||
sendIPCPacket(new IPCPacket16NBTList(IPCPacket16NBTList.WORLD_LIST, sendListNBT));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket14StringList.ID: {
|
||||
IPCPacket14StringList pkt = (IPCPacket14StringList) ipc;
|
||||
switch (pkt.opCode) {
|
||||
case IPCPacket14StringList.LOCALE:
|
||||
StringTranslate.initServer(pkt.stringList);
|
||||
break;
|
||||
// case IPCPacket14StringList.STAT_GUID:
|
||||
// AchievementMap.init(pkt.stringList);
|
||||
// AchievementList.init();
|
||||
// break;
|
||||
default:
|
||||
logger.error("Strange string list 0x{} with length{} recieved",
|
||||
Integer.toHexString(pkt.opCode), pkt.stringList.size());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket17ConfigureLAN.ID: {
|
||||
|
||||
IPCPacket17ConfigureLAN pkt = (IPCPacket17ConfigureLAN) ipc;
|
||||
if (!pkt.iceServers.isEmpty()
|
||||
&& ServerPlatformSingleplayer.getClientConfigAdapter().isAllowVoiceClient()) {
|
||||
currentProcess.enableVoice(pkt.iceServers.toArray(new String[pkt.iceServers.size()]));
|
||||
}
|
||||
currentProcess.getConfigurationManager().configureLAN(pkt.gamemode, pkt.cheats); // don't use
|
||||
// iceServers
|
||||
|
||||
break;
|
||||
}
|
||||
case IPCPacket18ClearPlayers.ID: {
|
||||
if (!isServerStopped()) {
|
||||
logger.error("Client tried to clear players while server was running");
|
||||
sendTaskFailed();
|
||||
} else {
|
||||
saveFormat.clearPlayers(((IPCPacket18ClearPlayers) ipc).worldName);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket18ClearPlayers.ID));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket19Autosave.ID: {
|
||||
if (!isServerStopped()) {
|
||||
currentProcess.getConfigurationManager().saveAllPlayerData();
|
||||
currentProcess.saveAllWorlds(false);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket19Autosave.ID));
|
||||
} else {
|
||||
logger.error("Client tried to autosave while server was stopped");
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket21EnableLogging.ID: {
|
||||
enableLoggingRedirector(((IPCPacket21EnableLogging) ipc).enable);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logger.error("Strange string list 0x{} with length{} recieved", Integer.toHexString(pkt.opCode), pkt.stringList.size());
|
||||
logger.error("IPC packet type 0x{} class \"{}\" was not handled", Integer.toHexString(id),
|
||||
ipc.getClass().getSimpleName());
|
||||
sendTaskFailed();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket17ConfigureLAN.ID: {
|
||||
|
||||
IPCPacket17ConfigureLAN pkt = (IPCPacket17ConfigureLAN)ipc;
|
||||
if(!pkt.iceServers.isEmpty() && ServerPlatformSingleplayer.getClientConfigAdapter().isAllowVoiceClient()) {
|
||||
currentProcess.enableVoice(pkt.iceServers.toArray(new String[pkt.iceServers.size()]));
|
||||
}
|
||||
currentProcess.getConfigurationManager().configureLAN(pkt.gamemode, pkt.cheats); // don't use iceServers
|
||||
|
||||
break;
|
||||
}
|
||||
case IPCPacket18ClearPlayers.ID: {
|
||||
if(!isServerStopped()) {
|
||||
logger.error("Client tried to clear players while server was running");
|
||||
sendTaskFailed();
|
||||
}else {
|
||||
saveFormat.clearPlayers(((IPCPacket18ClearPlayers)ipc).worldName);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket18ClearPlayers.ID));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket19Autosave.ID: {
|
||||
if(!isServerStopped()) {
|
||||
currentProcess.getConfigurationManager().saveAllPlayerData();
|
||||
currentProcess.saveAllWorlds(false);
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket19Autosave.ID));
|
||||
}else {
|
||||
logger.error("Client tried to autosave while server was stopped");
|
||||
sendTaskFailed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPacket21EnableLogging.ID: {
|
||||
enableLoggingRedirector(((IPCPacket21EnableLogging)ipc).enable);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logger.error("IPC packet type 0x{} class \"{}\" was not handled", Integer.toHexString(id), ipc.getClass().getSimpleName());
|
||||
sendTaskFailed();
|
||||
break;
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
logger.error("IPC packet type 0x{} class \"{}\" was not processed correctly", Integer.toHexString(id), ipc.getClass().getSimpleName());
|
||||
} catch (Throwable t) {
|
||||
logger.error("IPC packet type 0x{} class \"{}\" was not processed correctly", Integer.toHexString(id),
|
||||
ipc.getClass().getSimpleName());
|
||||
logger.error(t);
|
||||
sendIPCPacket(new IPCPacket15Crashed("IPC packet type 0x" + Integer.toHexString(id) + " class \"" + ipc.getClass().getSimpleName() + "\" was not processed correctly!\n\n" + EagRuntime.getStackTrace(t)));
|
||||
sendIPCPacket(new IPCPacket15Crashed(
|
||||
"IPC packet type 0x" + Integer.toHexString(id) + " class \"" + ipc.getClass().getSimpleName()
|
||||
+ "\" was not processed correctly!\n\n" + EagRuntime.getStackTrace(t)));
|
||||
sendTaskFailed();
|
||||
}
|
||||
}
|
||||
|
@ -423,7 +445,7 @@ public class EaglerIntegratedServerWorker {
|
|||
byte[] pkt;
|
||||
try {
|
||||
pkt = IPCPacketManager.IPCSerialize(ipc);
|
||||
}catch (IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to serialize IPC packet", ex);
|
||||
}
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(SingleplayerServerController.IPC_CHANNEL, pkt));
|
||||
|
@ -446,7 +468,7 @@ public class EaglerIntegratedServerWorker {
|
|||
}
|
||||
|
||||
private static void tryStopServer() {
|
||||
if(!isServerStopped()) {
|
||||
if (!isServerStopped()) {
|
||||
currentProcess.stopServer();
|
||||
}
|
||||
currentProcess = null;
|
||||
|
@ -454,17 +476,17 @@ public class EaglerIntegratedServerWorker {
|
|||
|
||||
private static void mainLoop() {
|
||||
processAsyncMessageQueue();
|
||||
|
||||
if(currentProcess != null) {
|
||||
if(currentProcess.isServerRunning()) {
|
||||
|
||||
if (currentProcess != null) {
|
||||
if (currentProcess.isServerRunning()) {
|
||||
currentProcess.mainLoop();
|
||||
}
|
||||
if(!currentProcess.isServerRunning()) {
|
||||
if (!currentProcess.isServerRunning()) {
|
||||
currentProcess.stopServer();
|
||||
currentProcess = null;
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacket01StopServer.ID));
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
EagUtils.sleep(50l);
|
||||
}
|
||||
}
|
||||
|
@ -473,29 +495,29 @@ public class EaglerIntegratedServerWorker {
|
|||
try {
|
||||
currentProcess = null;
|
||||
logger.info("Starting EaglercraftX integrated server worker...");
|
||||
|
||||
|
||||
// signal thread startup successful
|
||||
sendIPCPacket(new IPCPacketFFProcessKeepAlive(0xFF));
|
||||
|
||||
while(true) {
|
||||
|
||||
while (true) {
|
||||
mainLoop();
|
||||
EagUtils.sleep(1l);
|
||||
}
|
||||
}catch(Throwable tt) {
|
||||
if(tt instanceof ReportedException) {
|
||||
String fullReport = ((ReportedException)tt).getCrashReport().getCompleteReport();
|
||||
} catch (Throwable tt) {
|
||||
if (tt instanceof ReportedException) {
|
||||
String fullReport = ((ReportedException) tt).getCrashReport().getCompleteReport();
|
||||
logger.error(fullReport);
|
||||
sendIPCPacket(new IPCPacket15Crashed(fullReport));
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Server process encountered a fatal error!");
|
||||
logger.error(tt);
|
||||
sendIPCPacket(new IPCPacket15Crashed("SERVER PROCESS EXITED!\n\n" + EagRuntime.getStackTrace(tt)));
|
||||
}
|
||||
}finally {
|
||||
if(!isServerStopped()) {
|
||||
} finally {
|
||||
if (!isServerStopped()) {
|
||||
try {
|
||||
currentProcess.stopServer();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Encountered exception while stopping server!");
|
||||
logger.error(t);
|
||||
}
|
||||
|
|
|
@ -21,16 +21,24 @@ import net.lax1dude.eaglercraft.v1_8.sp.server.skins.IntegratedSkinService;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.server.voice.IntegratedVoiceService;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -61,7 +69,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
private final List<Runnable> scheduledTasks = new LinkedList();
|
||||
|
||||
public EaglerMinecraftServer(String world, String owner, int viewDistance, WorldSettings currentWorldSettings, boolean demo) {
|
||||
public EaglerMinecraftServer(String world, String owner, int viewDistance, WorldSettings currentWorldSettings,
|
||||
boolean demo) {
|
||||
super(world);
|
||||
Bootstrap.register();
|
||||
this.saveHandler = new EaglerSaveHandler(savesDir, world);
|
||||
|
@ -91,18 +100,18 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
}
|
||||
|
||||
public void enableVoice(String[] iceServers) {
|
||||
if(iceServers != null) {
|
||||
if(voiceService != null) {
|
||||
if (iceServers != null) {
|
||||
if (voiceService != null) {
|
||||
voiceService.changeICEServers(iceServers);
|
||||
}else {
|
||||
} else {
|
||||
voiceService = new IntegratedVoiceService(iceServers);
|
||||
for(EntityPlayerMP player : getConfigurationManager().func_181057_v()) {
|
||||
for (EntityPlayerMP player : getConfigurationManager().func_181057_v()) {
|
||||
voiceService.handlePlayerLoggedIn(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setBaseServerProperties(EnumDifficulty difficulty, GameType gamemode) {
|
||||
this.difficulty = difficulty;
|
||||
this.gamemode = gamemode;
|
||||
|
@ -134,7 +143,7 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
public void mainLoop() {
|
||||
long k = getCurrentTimeMillis();
|
||||
this.sendTPSToClient(k);
|
||||
if(paused && this.playersOnline.size() <= 1) {
|
||||
if (paused && this.playersOnline.size() <= 1) {
|
||||
currentTime = k;
|
||||
return;
|
||||
}
|
||||
|
@ -174,18 +183,17 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
}
|
||||
|
||||
protected void sendTPSToClient(long millis) {
|
||||
if(millis - lastTPSUpdate > 1000l) {
|
||||
if (millis - lastTPSUpdate > 1000l) {
|
||||
lastTPSUpdate = millis;
|
||||
if(serverRunning && this.worldServers != null) {
|
||||
if (serverRunning && this.worldServers != null) {
|
||||
List<String> lst = new ArrayList<>(Arrays.asList(
|
||||
"TPS: " + counterTicksPerSecond + "/20",
|
||||
"Chunks: " + countChunksLoaded(this.worldServers) + "/" + countChunksTotal(this.worldServers),
|
||||
"Entities: " + countEntities(this.worldServers) + "+" + countTileEntities(this.worldServers),
|
||||
"R: " + counterChunkRead + ", G: " + counterChunkGenerate + ", W: " + counterChunkWrite,
|
||||
"TU: " + counterTileUpdate + ", LU: " + counterLightUpdate
|
||||
));
|
||||
"TU: " + counterTileUpdate + ", LU: " + counterLightUpdate));
|
||||
int players = countPlayerEntities(this.worldServers);
|
||||
if(players > 1) {
|
||||
if (players > 1) {
|
||||
lst.add("Players: " + players);
|
||||
}
|
||||
counterTicksPerSecond = counterChunkRead = counterChunkGenerate = 0;
|
||||
|
@ -197,8 +205,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
private static int countChunksLoaded(WorldServer[] worlds) {
|
||||
int i = 0;
|
||||
for(int j = 0; j < worlds.length; ++j) {
|
||||
if(worlds[j] != null) {
|
||||
for (int j = 0; j < worlds.length; ++j) {
|
||||
if (worlds[j] != null) {
|
||||
i += worlds[j].theChunkProviderServer.getLoadedChunkCount();
|
||||
}
|
||||
}
|
||||
|
@ -207,11 +215,11 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
private static int countChunksTotal(WorldServer[] worlds) {
|
||||
int i = 0;
|
||||
for(int j = 0; j < worlds.length; ++j) {
|
||||
if(worlds[j] != null) {
|
||||
for (int j = 0; j < worlds.length; ++j) {
|
||||
if (worlds[j] != null) {
|
||||
List<EntityPlayer> players = worlds[j].playerEntities;
|
||||
for(int l = 0, n = players.size(); l < n; ++l) {
|
||||
i += ((EntityPlayerMP)players.get(l)).loadedChunks.size();
|
||||
for (int l = 0, n = players.size(); l < n; ++l) {
|
||||
i += ((EntityPlayerMP) players.get(l)).loadedChunks.size();
|
||||
}
|
||||
i += worlds[j].theChunkProviderServer.getLoadedChunkCount();
|
||||
}
|
||||
|
@ -221,8 +229,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
private static int countEntities(WorldServer[] worlds) {
|
||||
int i = 0;
|
||||
for(int j = 0; j < worlds.length; ++j) {
|
||||
if(worlds[j] != null) {
|
||||
for (int j = 0; j < worlds.length; ++j) {
|
||||
if (worlds[j] != null) {
|
||||
i += worlds[j].loadedEntityList.size();
|
||||
}
|
||||
}
|
||||
|
@ -231,8 +239,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
private static int countTileEntities(WorldServer[] worlds) {
|
||||
int i = 0;
|
||||
for(int j = 0; j < worlds.length; ++j) {
|
||||
if(worlds[j] != null) {
|
||||
for (int j = 0; j < worlds.length; ++j) {
|
||||
if (worlds[j] != null) {
|
||||
i += worlds[j].loadedTileEntityList.size();
|
||||
}
|
||||
}
|
||||
|
@ -241,8 +249,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
private static int countPlayerEntities(WorldServer[] worlds) {
|
||||
int i = 0;
|
||||
for(int j = 0; j < worlds.length; ++j) {
|
||||
if(worlds[j] != null) {
|
||||
for (int j = 0; j < worlds.length; ++j) {
|
||||
if (worlds[j] != null) {
|
||||
i += worlds[j].playerEntities.size();
|
||||
}
|
||||
}
|
||||
|
@ -251,18 +259,19 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
public void setPaused(boolean p) {
|
||||
paused = p;
|
||||
if(!p) {
|
||||
if (!p) {
|
||||
currentTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean getPaused() {
|
||||
return paused;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStructuresSpawn() {
|
||||
return worldServers != null ? worldServers[0].getWorldInfo().isMapFeaturesEnabled() : newWorldSettings.isMapFeaturesEnabled();
|
||||
return worldServers != null ? worldServers[0].getWorldInfo().isMapFeaturesEnabled()
|
||||
: newWorldSettings.isMapFeaturesEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -277,7 +286,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
|
||||
@Override
|
||||
public boolean isHardcore() {
|
||||
return worldServers != null ? worldServers[0].getWorldInfo().isHardcoreModeEnabled() : newWorldSettings.getHardcoreEnabled();
|
||||
return worldServers != null ? worldServers[0].getWorldInfo().isHardcoreModeEnabled()
|
||||
: newWorldSettings.getHardcoreEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,16 +14,24 @@ import net.minecraft.nbt.CompressedStreamTools;
|
|||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -36,7 +44,7 @@ public class WorldConverterEPK {
|
|||
logger.info("Importing world \"{}\" from EPK", newName);
|
||||
String folderName = newName.replaceAll("[\\./\"]", "_");
|
||||
VFile2 worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
while((new VFile2(worldDir, "level.dat")).exists() || (new VFile2(worldDir, "level.dat_old")).exists()) {
|
||||
while ((new VFile2(worldDir, "level.dat")).exists() || (new VFile2(worldDir, "level.dat_old")).exists()) {
|
||||
folderName += "_";
|
||||
worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
}
|
||||
|
@ -47,22 +55,22 @@ public class WorldConverterEPK {
|
|||
String hasReadType = null;
|
||||
boolean has152Format = false;
|
||||
int cnt = 0;
|
||||
while((f = dc.readFile()) != null) {
|
||||
while ((f = dc.readFile()) != null) {
|
||||
byte[] b = f.data;
|
||||
if(hasReadType == null) {
|
||||
if (hasReadType == null) {
|
||||
if (f.type.equals("HEAD") && f.name.equals("file-type")
|
||||
&& ((hasReadType = EPKDecompiler.readASCII(f.data)).equals("epk/world188")
|
||||
|| (has152Format = hasReadType.equals("epk/world152")))) {
|
||||
if(has152Format) {
|
||||
if (has152Format) {
|
||||
logger.warn("World type detected as 1.5.2, it will be converted to 1.8.8 format");
|
||||
}
|
||||
continue;
|
||||
}else {
|
||||
} else {
|
||||
throw new IOException("file does not contain a singleplayer 1.5.2 or 1.8.8 world!");
|
||||
}
|
||||
}
|
||||
if(f.type.equals("FILE")) {
|
||||
if(f.name.equals("level.dat") || f.name.equals("level.dat_old")) {
|
||||
if (f.type.equals("FILE")) {
|
||||
if (f.name.equals("level.dat") || f.name.equals("level.dat_old")) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
|
||||
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
|
||||
|
@ -74,7 +82,7 @@ public class WorldConverterEPK {
|
|||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
++cnt;
|
||||
if(prog - lastProgUpdate > 25000) {
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
logger.info("Extracted {} files, {} bytes from EPK...", cnt, prog);
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.1", prog);
|
||||
|
@ -83,9 +91,10 @@ public class WorldConverterEPK {
|
|||
}
|
||||
logger.info("EPK was successfully extracted into directory \"{}\"", worldDir.getPath());
|
||||
String[] worldsTxt = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if(worldsTxt == null || worldsTxt.length <= 0 || (worldsTxt.length == 1 && worldsTxt[0].trim().length() <= 0)) {
|
||||
if (worldsTxt == null || worldsTxt.length <= 0
|
||||
|| (worldsTxt.length == 1 && worldsTxt[0].trim().length() <= 0)) {
|
||||
worldsTxt = new String[] { folderName };
|
||||
}else {
|
||||
} else {
|
||||
String[] tmp = worldsTxt;
|
||||
worldsTxt = new String[worldsTxt.length + 1];
|
||||
System.arraycopy(tmp, 0, worldsTxt, 0, tmp.length);
|
||||
|
@ -97,13 +106,14 @@ public class WorldConverterEPK {
|
|||
public static byte[] exportWorld(String worldName) {
|
||||
String realWorldName = worldName;
|
||||
String worldOwner = "UNKNOWN";
|
||||
String splitter = new String(new char[] { (char)253, (char)233, (char)233 });
|
||||
if(worldName.contains(splitter)) {
|
||||
String splitter = new String(new char[] { (char) 253, (char) 233, (char) 233 });
|
||||
if (worldName.contains(splitter)) {
|
||||
int i = worldName.lastIndexOf(splitter);
|
||||
worldOwner = worldName.substring(i + 3);
|
||||
realWorldName = worldName.substring(0, i);
|
||||
}
|
||||
VFile2 worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(realWorldName, false).getWorldDirectory();
|
||||
VFile2 worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(realWorldName, false)
|
||||
.getWorldDirectory();
|
||||
logger.info("Exporting world directory \"{}\" as EPK", worldDir.getPath());
|
||||
final int[] bytesWritten = new int[1];
|
||||
final int[] filesWritten = new int[1];
|
||||
|
@ -111,7 +121,7 @@ public class WorldConverterEPK {
|
|||
EPKCompiler c = new EPKCompiler(realWorldName, worldOwner, "epk/world188");
|
||||
String pfx = worldDir.getPath();
|
||||
List<VFile2> filesList = worldDir.listFiles(true);
|
||||
for(int i = 0, l = filesList.size(); i < l; ++i) {
|
||||
for (int i = 0, l = filesList.size(); i < l; ++i) {
|
||||
VFile2 vf = filesList.get(i);
|
||||
++filesWritten[0];
|
||||
byte[] b = vf.getAllBytes();
|
||||
|
|
|
@ -24,16 +24,24 @@ import net.minecraft.nbt.CompressedStreamTools;
|
|||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -46,22 +54,27 @@ public class WorldConverterMCA {
|
|||
logger.info("Importing world \"{}\" from MCA", newName);
|
||||
String folderName = newName.replaceAll("[\\./\"]", "_");
|
||||
VFile2 worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
while((new VFile2(worldDir, "level.dat")).exists() || (new VFile2(worldDir, "level.dat_old")).exists()) {
|
||||
while ((new VFile2(worldDir, "level.dat")).exists() || (new VFile2(worldDir, "level.dat_old")).exists()) {
|
||||
folderName += "_";
|
||||
worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
}
|
||||
ZipInputStream zis = new ZipInputStream(new EaglerInputStream(archiveContents));
|
||||
ZipEntry folderNameFile = null;
|
||||
List<char[]> fileNames = new ArrayList<>();
|
||||
while((folderNameFile = zis.getNextEntry()) != null) {
|
||||
if (folderNameFile.getName().contains("__MACOSX/")) continue;
|
||||
if (folderNameFile.isDirectory()) continue;
|
||||
while ((folderNameFile = zis.getNextEntry()) != null) {
|
||||
if (folderNameFile.getName().contains("__MACOSX/"))
|
||||
continue;
|
||||
if (folderNameFile.isDirectory())
|
||||
continue;
|
||||
String lowerName = folderNameFile.getName().toLowerCase();
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr"))) continue;
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca")
|
||||
|| lowerName.endsWith(".mcr")))
|
||||
continue;
|
||||
fileNames.add(folderNameFile.getName().toCharArray());
|
||||
}
|
||||
final int[] i = new int[] { 0 };
|
||||
while(fileNames.get(0).length > i[0] && fileNames.stream().allMatch(w -> w[i[0]] == fileNames.get(0)[i[0]])) i[0]++;
|
||||
while (fileNames.get(0).length > i[0] && fileNames.stream().allMatch(w -> w[i[0]] == fileNames.get(0)[i[0]]))
|
||||
i[0]++;
|
||||
int folderPrefixOffset = i[0];
|
||||
zis = new ZipInputStream(new EaglerInputStream(archiveContents));
|
||||
ZipEntry f = null;
|
||||
|
@ -69,10 +82,14 @@ public class WorldConverterMCA {
|
|||
int prog = 0;
|
||||
byte[] bb = new byte[16384];
|
||||
while ((f = zis.getNextEntry()) != null) {
|
||||
if (f.getName().contains("__MACOSX/")) continue;
|
||||
if (f.isDirectory()) continue;
|
||||
if (f.getName().contains("__MACOSX/"))
|
||||
continue;
|
||||
if (f.isDirectory())
|
||||
continue;
|
||||
String lowerName = f.getName().toLowerCase();
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr") || lowerName.endsWith(".bmp"))) continue;
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca")
|
||||
|| lowerName.endsWith(".mcr") || lowerName.endsWith(".bmp")))
|
||||
continue;
|
||||
EaglerOutputStream baos = new EaglerOutputStream();
|
||||
int len;
|
||||
while ((len = zis.read(bb)) != -1) {
|
||||
|
@ -102,30 +119,33 @@ public class WorldConverterMCA {
|
|||
VFile2 ff = new VFile2(worldDir, fileName);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
} else if ((fileName.endsWith(".mcr") || fileName.endsWith(".mca")) && (fileName.startsWith("region/") || fileName.startsWith("DIM1/region/") || fileName.startsWith("DIM-1/region/"))) {
|
||||
VFile2 chunkFolder = new VFile2(worldDir, fileName.startsWith("DIM1") ? "level1" : (fileName.startsWith("DIM-1") ? "level-1" : "level0"));
|
||||
} else if ((fileName.endsWith(".mcr") || fileName.endsWith(".mca")) && (fileName.startsWith("region/")
|
||||
|| fileName.startsWith("DIM1/region/") || fileName.startsWith("DIM-1/region/"))) {
|
||||
VFile2 chunkFolder = new VFile2(worldDir,
|
||||
fileName.startsWith("DIM1") ? "level1" : (fileName.startsWith("DIM-1") ? "level-1" : "level0"));
|
||||
RegionFile mca = new RegionFile(new RandomAccessMemoryFile(b, b.length));
|
||||
int loadChunksCount = 0;
|
||||
for(int j = 0; j < 32; ++j) {
|
||||
for(int k = 0; k < 32; ++k) {
|
||||
if(mca.isChunkSaved(j, k)) {
|
||||
for (int j = 0; j < 32; ++j) {
|
||||
for (int k = 0; k < 32; ++k) {
|
||||
if (mca.isChunkSaved(j, k)) {
|
||||
NBTTagCompound chunkNBT;
|
||||
NBTTagCompound chunkLevel;
|
||||
try {
|
||||
chunkNBT = CompressedStreamTools.read(mca.getChunkDataInputStream(j, k));
|
||||
if(!chunkNBT.hasKey("Level", 10)) {
|
||||
if (!chunkNBT.hasKey("Level", 10)) {
|
||||
throw new IOException("Chunk is missing level data!");
|
||||
}
|
||||
chunkLevel = chunkNBT.getCompoundTag("Level");
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("{}: Could not read chunk: {}, {}", fileName, j, k);
|
||||
logger.error(t);
|
||||
continue;
|
||||
}
|
||||
int chunkX = chunkLevel.getInteger("xPos");
|
||||
int chunkZ = chunkLevel.getInteger("zPos");
|
||||
VFile2 chunkOut = new VFile2(chunkFolder, EaglerChunkLoader.getChunkPath(chunkX, chunkZ) + ".dat");
|
||||
if(chunkOut.exists()) {
|
||||
VFile2 chunkOut = new VFile2(chunkFolder,
|
||||
EaglerChunkLoader.getChunkPath(chunkX, chunkZ) + ".dat");
|
||||
if (chunkOut.exists()) {
|
||||
logger.error("{}: Chunk already exists: {}", fileName, chunkOut.getPath());
|
||||
continue;
|
||||
}
|
||||
|
@ -144,8 +164,9 @@ public class WorldConverterMCA {
|
|||
}
|
||||
logger.info("{}: Imported {} chunks successfully ({} bytes)", fileName, loadChunksCount, prog);
|
||||
} else if (fileName.startsWith("playerdata/") || fileName.startsWith("stats/")) {
|
||||
//TODO: LAN player inventories
|
||||
} else if (fileName.startsWith("data/") || fileName.startsWith("players/") || fileName.startsWith("eagler/skulls/")) {
|
||||
// TODO: LAN player inventories
|
||||
} else if (fileName.startsWith("data/") || fileName.startsWith("players/")
|
||||
|| fileName.startsWith("eagler/skulls/")) {
|
||||
VFile2 ff = new VFile2(worldDir, fileName);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
|
@ -159,9 +180,10 @@ public class WorldConverterMCA {
|
|||
}
|
||||
logger.info("MCA was successfully extracted into directory \"{}\"", worldDir.getPath());
|
||||
String[] worldsTxt = EaglerSaveFormat.worldsList.getAllLines();
|
||||
if(worldsTxt == null || worldsTxt.length <= 0 || (worldsTxt.length == 1 && worldsTxt[0].trim().length() <= 0)) {
|
||||
if (worldsTxt == null || worldsTxt.length <= 0
|
||||
|| (worldsTxt.length == 1 && worldsTxt[0].trim().length() <= 0)) {
|
||||
worldsTxt = new String[] { folderName };
|
||||
}else {
|
||||
} else {
|
||||
String[] tmp = worldsTxt;
|
||||
worldsTxt = new String[worldsTxt.length + 1];
|
||||
System.arraycopy(tmp, 0, worldsTxt, 0, tmp.length);
|
||||
|
@ -174,14 +196,15 @@ public class WorldConverterMCA {
|
|||
EaglerOutputStream bao = new EaglerOutputStream();
|
||||
ZipOutputStream zos = new ZipOutputStream(bao);
|
||||
zos.setComment("contains backup of world '" + folderName + "'");
|
||||
VFile2 worldFolder = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
VFile2 worldFolder = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false)
|
||||
.getWorldDirectory();
|
||||
logger.info("Exporting world directory \"{}\" as MCA", worldFolder.getPath());
|
||||
VFile2 vf = new VFile2(worldFolder, "level.dat");
|
||||
byte[] b;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
boolean safe = false;
|
||||
if(vf.exists()) {
|
||||
if (vf.exists()) {
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/level.dat"));
|
||||
b = vf.getAllBytes();
|
||||
zos.write(b);
|
||||
|
@ -189,7 +212,7 @@ public class WorldConverterMCA {
|
|||
safe = true;
|
||||
}
|
||||
vf = new VFile2(worldFolder, "level.dat_old");
|
||||
if(vf.exists()) {
|
||||
if (vf.exists()) {
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/level.dat_old"));
|
||||
b = vf.getAllBytes();
|
||||
zos.write(b);
|
||||
|
@ -203,24 +226,24 @@ public class WorldConverterMCA {
|
|||
String[] srcFolderNames = new String[] { "level0", "level-1", "level1" };
|
||||
String[] dstFolderNames = new String[] { "/region/", "/DIM-1/region/", "/DIM1/region/" };
|
||||
List<VFile2> fileList;
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
vf = new VFile2(worldFolder, srcFolderNames[i]);
|
||||
fileList = vf.listFiles(true);
|
||||
String regionFolder = folderName + dstFolderNames[i];
|
||||
logger.info("Converting chunks in \"{}\" as MCA to \"{}\"...", vf.getPath(), regionFolder);
|
||||
Map<String,RegionFile> regionFiles = new HashMap();
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
Map<String, RegionFile> regionFiles = new HashMap();
|
||||
for (int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 chunkFile = fileList.get(k);
|
||||
NBTTagCompound chunkNBT;
|
||||
NBTTagCompound chunkLevel;
|
||||
try {
|
||||
b = chunkFile.getAllBytes();
|
||||
chunkNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
if(!chunkNBT.hasKey("Level", 10)) {
|
||||
if (!chunkNBT.hasKey("Level", 10)) {
|
||||
throw new IOException("Chunk is missing level data!");
|
||||
}
|
||||
chunkLevel = chunkNBT.getCompoundTag("Level");
|
||||
}catch(IOException t) {
|
||||
} catch (IOException t) {
|
||||
logger.error("Could not read chunk: {}", chunkFile.getPath());
|
||||
logger.error(t);
|
||||
continue;
|
||||
|
@ -229,13 +252,13 @@ public class WorldConverterMCA {
|
|||
int chunkZ = chunkLevel.getInteger("zPos");
|
||||
String regionFileName = "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mca";
|
||||
RegionFile rf = regionFiles.get(regionFileName);
|
||||
if(rf == null) {
|
||||
if (rf == null) {
|
||||
rf = new RegionFile(new RandomAccessMemoryFile(new byte[65536], 0));
|
||||
regionFiles.put(regionFileName, rf);
|
||||
}
|
||||
try(DataOutputStream dos = rf.getChunkDataOutputStream(chunkX & 31, chunkZ & 31)) {
|
||||
try (DataOutputStream dos = rf.getChunkDataOutputStream(chunkX & 31, chunkZ & 31)) {
|
||||
CompressedStreamTools.write(chunkNBT, dos);
|
||||
}catch(IOException t) {
|
||||
} catch (IOException t) {
|
||||
logger.error("Could not write chunk to {}: {}", regionFileName, chunkFile.getPath());
|
||||
logger.error(t);
|
||||
continue;
|
||||
|
@ -246,11 +269,11 @@ public class WorldConverterMCA {
|
|||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
if(regionFiles.isEmpty()) {
|
||||
if (regionFiles.isEmpty()) {
|
||||
logger.info("No region files were generated");
|
||||
continue;
|
||||
}
|
||||
for(Entry<String,RegionFile> etr : regionFiles.entrySet()) {
|
||||
for (Entry<String, RegionFile> etr : regionFiles.entrySet()) {
|
||||
String regionPath = regionFolder + etr.getKey();
|
||||
logger.info("Writing region file: {}", regionPath);
|
||||
zos.putNextEntry(new ZipEntry(regionPath));
|
||||
|
@ -259,7 +282,7 @@ public class WorldConverterMCA {
|
|||
}
|
||||
logger.info("Copying extra world data...");
|
||||
fileList = (new VFile2(worldFolder, "data")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
for (int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/data/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
|
@ -271,7 +294,7 @@ public class WorldConverterMCA {
|
|||
}
|
||||
}
|
||||
fileList = (new VFile2(worldFolder, "players")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
for (int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/players/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
|
@ -283,7 +306,7 @@ public class WorldConverterMCA {
|
|||
}
|
||||
}
|
||||
fileList = (new VFile2(worldFolder, "eagler/skulls")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
for (int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/eagler/skulls/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
|
|
|
@ -28,16 +28,24 @@ import net.minecraft.util.ITickable;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.server.internal.ServerPlatformSingleplayer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -60,61 +68,62 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
|
||||
public static final int fragmentSize = 0xFF00;
|
||||
public static final int compressionThreshold = 1024;
|
||||
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("NetworkManager");
|
||||
|
||||
public IntegratedServerPlayerNetworkManager(String playerChannel) {
|
||||
if(temporaryBuffer == null) {
|
||||
if (temporaryBuffer == null) {
|
||||
temporaryBuffer = new PacketBuffer(Unpooled.buffer(0x1FFFF));
|
||||
}
|
||||
this.playerChannel = playerChannel;
|
||||
this.enableSendCompression = !SingleplayerServerController.PLAYER_CHANNEL.equals(playerChannel);
|
||||
if(this.enableSendCompression) {
|
||||
if(temporaryOutputStream == null) {
|
||||
if (this.enableSendCompression) {
|
||||
if (temporaryOutputStream == null) {
|
||||
temporaryOutputStream = new EaglerOutputStream(16386);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void connect() {
|
||||
fragmentedPacket.clear();
|
||||
firstPacket = true;
|
||||
}
|
||||
|
||||
|
||||
public EnumEaglerConnectionState getConnectStatus() {
|
||||
return EaglerIntegratedServerWorker.getChannelExists(playerChannel) ? EnumEaglerConnectionState.CONNECTED : EnumEaglerConnectionState.CLOSED;
|
||||
return EaglerIntegratedServerWorker.getChannelExists(playerChannel) ? EnumEaglerConnectionState.CONNECTED
|
||||
: EnumEaglerConnectionState.CLOSED;
|
||||
}
|
||||
|
||||
|
||||
public void closeChannel(IChatComponent reason) {
|
||||
EaglerIntegratedServerWorker.closeChannel(playerChannel);
|
||||
if(nethandler != null) {
|
||||
if (nethandler != null) {
|
||||
nethandler.onDisconnect(reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setConnectionState(EnumConnectionState state) {
|
||||
packetState = state;
|
||||
}
|
||||
|
||||
public void addRecievedPacket(byte[] next) {
|
||||
if(recievedPacketBufferCounter < recievedPacketBuffer.length - 1) {
|
||||
if (recievedPacketBufferCounter < recievedPacketBuffer.length - 1) {
|
||||
recievedPacketBuffer[recievedPacketBufferCounter++] = next;
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Dropping packets on recievedPacketBuffer for channel \"{}\"! (overflow)", playerChannel);
|
||||
}
|
||||
}
|
||||
|
||||
public void processReceivedPackets() {
|
||||
if(nethandler == null) return;
|
||||
if (nethandler == null)
|
||||
return;
|
||||
|
||||
|
||||
for(int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
for (int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
byte[] data = recievedPacketBuffer[i];
|
||||
byte[] fullData;
|
||||
|
||||
if(enableSendCompression) {
|
||||
if(firstPacket) {
|
||||
if(data.length > 2 && data[0] == (byte)0x02 && data[1] == (byte)0x3D) {
|
||||
if (enableSendCompression) {
|
||||
if (firstPacket) {
|
||||
if (data.length > 2 && data[0] == (byte) 0x02 && data[1] == (byte) 0x3D) {
|
||||
EaglerOutputStream kickPacketBAO = new EaglerOutputStream();
|
||||
try {
|
||||
DataOutputStream kickDAO = new DataOutputStream(kickPacketBAO);
|
||||
|
@ -123,15 +132,17 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
String msg = "This is an EaglercraftX 1.8 LAN world!";
|
||||
kickDAO.write(0x00);
|
||||
kickDAO.write(msg.length());
|
||||
for(int j = 0, l = msg.length(); j < l; ++j) {
|
||||
for (int j = 0, l = msg.length(); j < l; ++j) {
|
||||
kickDAO.write(0);
|
||||
kickDAO.write(msg.codePointAt(j));
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, kickPacketBAO.toByteArray()));
|
||||
closeChannel(new ChatComponentText("Recieved unsuppoorted connection from an Eaglercraft 1.5.2 client!"));
|
||||
ServerPlatformSingleplayer
|
||||
.sendPacket(new IPCPacketData(playerChannel, kickPacketBAO.toByteArray()));
|
||||
closeChannel(new ChatComponentText(
|
||||
"Recieved unsuppoorted connection from an Eaglercraft 1.5.2 client!"));
|
||||
firstPacket = false;
|
||||
recievedPacketBufferCounter = 0;
|
||||
return;
|
||||
|
@ -139,19 +150,19 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
firstPacket = false;
|
||||
}
|
||||
if (data[0] == 0) {
|
||||
if(fragmentedPacket.isEmpty()) {
|
||||
if (fragmentedPacket.isEmpty()) {
|
||||
fullData = new byte[data.length - 1];
|
||||
System.arraycopy(data, 1, fullData, 0, fullData.length);
|
||||
}else {
|
||||
} else {
|
||||
fragmentedPacket.add(data);
|
||||
int len = 0;
|
||||
int fragCount = fragmentedPacket.size();
|
||||
for(int j = 0; j < fragCount; ++j) {
|
||||
for (int j = 0; j < fragCount; ++j) {
|
||||
len += fragmentedPacket.get(j).length - 1;
|
||||
}
|
||||
fullData = new byte[len];
|
||||
len = 0;
|
||||
for(int j = 0; j < fragCount; ++j) {
|
||||
for (int j = 0; j < fragCount; ++j) {
|
||||
byte[] f = fragmentedPacket.get(j);
|
||||
System.arraycopy(f, 1, fullData, len, f.length - 1);
|
||||
len += f.length - 1;
|
||||
|
@ -162,14 +173,14 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
fragmentedPacket.add(data);
|
||||
continue;
|
||||
} else {
|
||||
logger.error("Recieved {} byte fragment of unknown type: {}", data.length, ((int)data[0] & 0xFF));
|
||||
logger.error("Recieved {} byte fragment of unknown type: {}", data.length, ((int) data[0] & 0xFF));
|
||||
continue;
|
||||
}
|
||||
|
||||
}else {
|
||||
|
||||
} else {
|
||||
fullData = data;
|
||||
}
|
||||
|
||||
|
||||
recievedPacketBuffer[i] = null;
|
||||
++debugPacketCounter;
|
||||
try {
|
||||
|
@ -177,33 +188,36 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
nettyBuffer.writerIndex(fullData.length);
|
||||
PacketBuffer input = new PacketBuffer(nettyBuffer);
|
||||
int pktId = input.readVarIntFromBuffer();
|
||||
|
||||
|
||||
Packet pkt;
|
||||
try {
|
||||
pkt = packetState.getPacket(EnumPacketDirection.SERVERBOUND, pktId);
|
||||
}catch(IllegalAccessException | InstantiationException ex) {
|
||||
} catch (IllegalAccessException | InstantiationException ex) {
|
||||
throw new IOException("Recieved a packet with type " + pktId + " which is invalid!");
|
||||
}
|
||||
|
||||
if(pkt == null) {
|
||||
throw new IOException("Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
if (pkt == null) {
|
||||
throw new IOException(
|
||||
"Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
}
|
||||
|
||||
try {
|
||||
pkt.readPacketData(input);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new IOException("Failed to read packet type '" + pkt.getClass().getSimpleName() + "'", t);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
pkt.processPacket(nethandler);
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.", pkt.getClass().getSimpleName());
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.",
|
||||
pkt.getClass().getSimpleName());
|
||||
logger.error(t);
|
||||
}
|
||||
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process socket frame {}! It'll be skipped for debug purposes.", debugPacketCounter);
|
||||
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process socket frame {}! It'll be skipped for debug purposes.",
|
||||
debugPacketCounter);
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
|
@ -211,30 +225,30 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
}
|
||||
|
||||
public void sendPacket(Packet pkt) {
|
||||
if(!isChannelOpen()) {
|
||||
if (!isChannelOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int i;
|
||||
try {
|
||||
i = packetState.getPacketId(EnumPacketDirection.CLIENTBOUND, pkt);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Incorrect packet for state: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
temporaryBuffer.clear();
|
||||
temporaryBuffer.writeVarIntToBuffer(i);
|
||||
try {
|
||||
pkt.writePacketData(temporaryBuffer);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Failed to write packet {}!", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int len = temporaryBuffer.readableBytes();
|
||||
if(enableSendCompression) {
|
||||
if(len > compressionThreshold) {
|
||||
if (enableSendCompression) {
|
||||
if (len > compressionThreshold) {
|
||||
temporaryOutputStream.reset();
|
||||
byte[] compressedData;
|
||||
try {
|
||||
|
@ -247,53 +261,55 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
temporaryBuffer.readBytes(os, len);
|
||||
os.close();
|
||||
compressedData = temporaryOutputStream.toByteArray();
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Failed to compress packet {}!", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
if(compressedData.length > fragmentSize) {
|
||||
if (compressedData.length > fragmentSize) {
|
||||
int fragmentSizeN1 = fragmentSize - 1;
|
||||
for (int j = 1; j < compressedData.length; j += fragmentSizeN1) {
|
||||
byte[] fragData = new byte[((j + fragmentSizeN1 > (compressedData.length - 1)) ? ((compressedData.length - 1) % fragmentSizeN1) : fragmentSizeN1) + 1];
|
||||
byte[] fragData = new byte[((j + fragmentSizeN1 > (compressedData.length - 1))
|
||||
? ((compressedData.length - 1) % fragmentSizeN1)
|
||||
: fragmentSizeN1) + 1];
|
||||
System.arraycopy(compressedData, j, fragData, 1, fragData.length - 1);
|
||||
fragData[0] = (j + fragmentSizeN1 < compressedData.length) ? (byte) 1 : (byte) 2;
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, fragData));
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, compressedData));
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
int fragmentSizeN1 = fragmentSize - 1;
|
||||
if(len > fragmentSizeN1) {
|
||||
if (len > fragmentSizeN1) {
|
||||
do {
|
||||
int readLen = len > fragmentSizeN1 ? fragmentSizeN1 : len;
|
||||
byte[] frag = new byte[readLen + 1];
|
||||
temporaryBuffer.readBytes(frag, 1, readLen);
|
||||
frag[0] = temporaryBuffer.readableBytes() == 0 ? (byte)0 : (byte)1;
|
||||
frag[0] = temporaryBuffer.readableBytes() == 0 ? (byte) 0 : (byte) 1;
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, frag));
|
||||
}while((len = temporaryBuffer.readableBytes()) > 0);
|
||||
}else {
|
||||
} while ((len = temporaryBuffer.readableBytes()) > 0);
|
||||
} else {
|
||||
byte[] bytes = new byte[len + 1];
|
||||
bytes[0] = 0;
|
||||
temporaryBuffer.readBytes(bytes, 1, len);
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, bytes));
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
byte[] bytes = new byte[len];
|
||||
temporaryBuffer.readBytes(bytes, 0, len);
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, bytes));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setNetHandler(INetHandler nethandler) {
|
||||
this.nethandler = nethandler;
|
||||
}
|
||||
|
||||
|
||||
public boolean isLocalChannel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean isChannelOpen() {
|
||||
return getConnectStatus() == EnumEaglerConnectionState.CONNECTED;
|
||||
}
|
||||
|
@ -308,8 +324,8 @@ public class IntegratedServerPlayerNetworkManager {
|
|||
|
||||
public void tick() {
|
||||
processReceivedPackets();
|
||||
if(nethandler instanceof ITickable) {
|
||||
((ITickable)nethandler).update();
|
||||
if (nethandler instanceof ITickable) {
|
||||
((ITickable) nethandler).update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,24 @@ import net.minecraft.util.ChatComponentTranslation;
|
|||
import net.minecraft.util.IChatComponent;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -57,7 +65,7 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
|||
public void closeChannel(IChatComponent reason) {
|
||||
LANServerController.closeLAN();
|
||||
SingleplayerServerController.closeLocalPlayerChannel();
|
||||
if(nethandler != null) {
|
||||
if (nethandler != null) {
|
||||
nethandler.onDisconnect(reason);
|
||||
}
|
||||
clearRecieveQueue();
|
||||
|
@ -65,18 +73,19 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
|||
}
|
||||
|
||||
public void addRecievedPacket(byte[] next) {
|
||||
if(recievedPacketBufferCounter < recievedPacketBuffer.length - 1) {
|
||||
if (recievedPacketBufferCounter < recievedPacketBuffer.length - 1) {
|
||||
recievedPacketBuffer[recievedPacketBufferCounter++] = next;
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Dropping packets on recievedPacketBuffer for channel \"{}\"! (overflow)", address);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processReceivedPackets() throws IOException {
|
||||
if(nethandler == null) return;
|
||||
if (nethandler == null)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
for (int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
byte[] next = recievedPacketBuffer[i];
|
||||
recievedPacketBuffer[i] = null;
|
||||
++debugPacketCounter;
|
||||
|
@ -85,33 +94,36 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
|||
nettyBuffer.writerIndex(next.length);
|
||||
PacketBuffer input = new PacketBuffer(nettyBuffer);
|
||||
int pktId = input.readVarIntFromBuffer();
|
||||
|
||||
|
||||
Packet pkt;
|
||||
try {
|
||||
pkt = packetState.getPacket(EnumPacketDirection.CLIENTBOUND, pktId);
|
||||
}catch(IllegalAccessException | InstantiationException ex) {
|
||||
} catch (IllegalAccessException | InstantiationException ex) {
|
||||
throw new IOException("Recieved a packet with type " + pktId + " which is invalid!");
|
||||
}
|
||||
|
||||
if(pkt == null) {
|
||||
throw new IOException("Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
|
||||
if (pkt == null) {
|
||||
throw new IOException(
|
||||
"Recieved packet type " + pktId + " which is undefined in state " + packetState);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
pkt.readPacketData(input);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new IOException("Failed to read packet type '" + pkt.getClass().getSimpleName() + "'", t);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
pkt.processPacket(nethandler);
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.", pkt.getClass().getSimpleName());
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process {}! It'll be skipped for debug purposes.",
|
||||
pkt.getClass().getSimpleName());
|
||||
logger.error(t);
|
||||
}
|
||||
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to process socket frame {}! It'll be skipped for debug purposes.", debugPacketCounter);
|
||||
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to process socket frame {}! It'll be skipped for debug purposes.",
|
||||
debugPacketCounter);
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
|
@ -120,38 +132,38 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
|||
|
||||
@Override
|
||||
public void sendPacket(Packet pkt) {
|
||||
if(!isChannelOpen()) {
|
||||
if (!isChannelOpen()) {
|
||||
logger.error("Packet was sent on a closed connection: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int i;
|
||||
try {
|
||||
i = packetState.getPacketId(EnumPacketDirection.SERVERBOUND, pkt);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Incorrect packet for state: {}", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
temporaryBuffer.clear();
|
||||
temporaryBuffer.writeVarIntToBuffer(i);
|
||||
try {
|
||||
pkt.writePacketData(temporaryBuffer);
|
||||
}catch(IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
logger.error("Failed to write packet {}!", pkt.getClass().getSimpleName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int len = temporaryBuffer.writerIndex();
|
||||
byte[] bytes = new byte[len];
|
||||
temporaryBuffer.getBytes(0, bytes);
|
||||
|
||||
|
||||
ClientPlatformSingleplayer.sendPacket(new IPCPacketData(address, bytes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkDisconnected() {
|
||||
if(!isPlayerChannelOpen) {
|
||||
if (!isPlayerChannelOpen) {
|
||||
try {
|
||||
processReceivedPackets(); // catch kick message
|
||||
} catch (IOException e) {
|
||||
|
@ -159,7 +171,7 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
|||
clearRecieveQueue();
|
||||
doClientDisconnect(new ChatComponentTranslation("disconnect.endOfStream"));
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +182,7 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
|||
}
|
||||
|
||||
public void clearRecieveQueue() {
|
||||
for(int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
for (int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
recievedPacketBuffer[i] = null;
|
||||
}
|
||||
recievedPacketBufferCounter = 0;
|
||||
|
|
|
@ -21,16 +21,24 @@ import net.minecraft.util.MathHelper;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -83,7 +91,7 @@ public class GuiVoiceMenu extends Gui {
|
|||
protected int voiceScreenButtonChangeRadiusposY;
|
||||
protected int voiceScreenButtonChangeRadiusposW;
|
||||
protected int voiceScreenButtonChangeRadiusposH;
|
||||
|
||||
|
||||
protected int voiceScreenVolumeIndicatorX;
|
||||
protected int voiceScreenVolumeIndicatorY;
|
||||
protected int voiceScreenVolumeIndicatorW;
|
||||
|
@ -104,16 +112,16 @@ public class GuiVoiceMenu extends Gui {
|
|||
|
||||
protected static boolean showingCompatWarning = false;
|
||||
protected static boolean showCompatWarning = true;
|
||||
|
||||
|
||||
protected static boolean showingTrackingWarning = false;
|
||||
protected static boolean showTrackingWarning = true;
|
||||
|
||||
|
||||
protected static EnumVoiceChannelType continueChannel = null;
|
||||
|
||||
|
||||
public GuiVoiceMenu(GuiScreen parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
public void setResolution(Minecraft mc, int w, int h) {
|
||||
this.mc = mc;
|
||||
this.fontRendererObj = mc.fontRendererObj;
|
||||
|
@ -121,98 +129,115 @@ public class GuiVoiceMenu extends Gui {
|
|||
this.height = h;
|
||||
initGui();
|
||||
}
|
||||
|
||||
|
||||
public void initGui() {
|
||||
this.sliderBlocks = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 20, 150, 20, (VoiceClientController.getVoiceProximity() - 5) / 17.0f, 1.0f) {
|
||||
this.sliderBlocks = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 20, 150, 20,
|
||||
(VoiceClientController.getVoiceProximity() - 5) / 17.0f, 1.0f) {
|
||||
public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
|
||||
if(super.mousePressed(par1Minecraft, par2, par3)) {
|
||||
this.displayString = "" + (int)((sliderValue * 17.0f) + 5.0f) + " Blocks";
|
||||
if (super.mousePressed(par1Minecraft, par2, par3)) {
|
||||
this.displayString = "" + (int) ((sliderValue * 17.0f) + 5.0f) + " Blocks";
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseDragged(Minecraft par1Minecraft, int par2, int par3) {
|
||||
super.mouseDragged(par1Minecraft, par2, par3);
|
||||
this.displayString = "" + (int)((sliderValue * 17.0f) + 5.0f) + " Blocks";
|
||||
this.displayString = "" + (int) ((sliderValue * 17.0f) + 5.0f) + " Blocks";
|
||||
}
|
||||
};
|
||||
sliderBlocks.displayString = "" + VoiceClientController.getVoiceProximity() + " Blocks";
|
||||
this.sliderListenVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 10, 150, 20, VoiceClientController.getVoiceListenVolume(), 1.0f);
|
||||
this.sliderSpeakVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 56, 150, 20, VoiceClientController.getVoiceSpeakVolume(), 1.0f);
|
||||
|
||||
this.sliderListenVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 10, 150, 20,
|
||||
VoiceClientController.getVoiceListenVolume(), 1.0f);
|
||||
this.sliderSpeakVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 56, 150, 20,
|
||||
VoiceClientController.getVoiceSpeakVolume(), 1.0f);
|
||||
|
||||
applyRadiusButton = new GuiButton(2, (width - 150) / 2, height / 3 + 49, 150, 20, I18n.format("voice.apply"));
|
||||
applyVolumeButton = new GuiButton(3, (width - 150) / 2, height / 3 + 90, 150, 20, I18n.format("voice.apply"));
|
||||
noticeContinueButton = new GuiButton(5, (width - 150) / 2, height / 3 + 60, 150, 20, I18n.format("voice.unsupportedWarning10"));
|
||||
noticeCancelButton = new GuiButton(6, (width - 150) / 2, height / 3 + 90, 150, 20, I18n.format("voice.unsupportedWarning11"));
|
||||
noticeContinueButton = new GuiButton(5, (width - 150) / 2, height / 3 + 60, 150, 20,
|
||||
I18n.format("voice.unsupportedWarning10"));
|
||||
noticeCancelButton = new GuiButton(6, (width - 150) / 2, height / 3 + 90, 150, 20,
|
||||
I18n.format("voice.unsupportedWarning11"));
|
||||
applyRadiusButton.visible = applyVolumeButton.visible = noticeContinueButton.visible = noticeCancelButton.visible = false;
|
||||
}
|
||||
|
||||
|
||||
private void drawButtons(int mx, int my, float partialTicks) {
|
||||
applyRadiusButton.drawButton(mc, mx, my);
|
||||
applyVolumeButton.drawButton(mc, mx, my);
|
||||
noticeContinueButton.drawButton(mc, mx, my);
|
||||
noticeCancelButton.drawButton(mc, mx, my);
|
||||
}
|
||||
|
||||
|
||||
public void drawScreen(int mx, int my, float partialTicks) {
|
||||
String txt = I18n.format("voice.title");
|
||||
drawString(fontRendererObj, txt, width - 5 - fontRendererObj.getStringWidth(txt), 5, 0xFFCC22);
|
||||
|
||||
|
||||
applyRadiusButton.visible = showSliderBlocks;
|
||||
applyVolumeButton.visible = showSliderVolume;
|
||||
|
||||
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
|
||||
|
||||
|
||||
if (showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
|
||||
|
||||
drawRect(0, 0, this.width, this.height, 0xB0101010);
|
||||
|
||||
if(showSliderBlocks) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 4 - 1, this.width / 2 + 86, height / 3 + 64 + height / 16, 0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 4 + 0, this.width / 2 + 85, height / 3 + 63 + height / 16, 0xFF333333);
|
||||
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.radiusTitle"), this.width / 2, height / 4 + 9, 16777215);
|
||||
drawString(this.fontRendererObj, I18n.format("voice.radiusLabel"), (this.width - 150) / 2 + 3, height / 3 + 6, 0xCCCCCC);
|
||||
|
||||
if (showSliderBlocks) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 4 - 1, this.width / 2 + 86, height / 3 + 64 + height / 16,
|
||||
0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 4 + 0, this.width / 2 + 85, height / 3 + 63 + height / 16,
|
||||
0xFF333333);
|
||||
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.radiusTitle"), this.width / 2,
|
||||
height / 4 + 9, 16777215);
|
||||
drawString(this.fontRendererObj, I18n.format("voice.radiusLabel"), (this.width - 150) / 2 + 3,
|
||||
height / 3 + 6, 0xCCCCCC);
|
||||
sliderBlocks.drawButton(mc, mx, my);
|
||||
|
||||
}else if(showSliderVolume) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 4 - 11, this.width / 2 + 86, height / 3 + 104 + height / 16, 0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 4 - 10, this.width / 2 + 85, height / 3 + 103 + height / 16, 0xFF333333);
|
||||
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.volumeTitle"), this.width / 2, height / 4 - 1, 16777215);
|
||||
drawString(this.fontRendererObj, I18n.format("voice.volumeListen"), (this.width - 150) / 2 + 3, height / 3 - 4, 0xCCCCCC);
|
||||
|
||||
} else if (showSliderVolume) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 4 - 11, this.width / 2 + 86, height / 3 + 104 + height / 16,
|
||||
0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 4 - 10, this.width / 2 + 85, height / 3 + 103 + height / 16,
|
||||
0xFF333333);
|
||||
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.volumeTitle"), this.width / 2,
|
||||
height / 4 - 1, 16777215);
|
||||
drawString(this.fontRendererObj, I18n.format("voice.volumeListen"), (this.width - 150) / 2 + 3,
|
||||
height / 3 - 4, 0xCCCCCC);
|
||||
sliderListenVolume.drawButton(mc, mx, my);
|
||||
|
||||
drawString(this.fontRendererObj, I18n.format("voice.volumeSpeak"), (this.width - 150) / 2 + 3, height / 3 + 42, 0xCCCCCC);
|
||||
|
||||
drawString(this.fontRendererObj, I18n.format("voice.volumeSpeak"), (this.width - 150) / 2 + 3,
|
||||
height / 3 + 42, 0xCCCCCC);
|
||||
sliderSpeakVolume.drawButton(mc, mx, my);
|
||||
|
||||
}else if(showPTTKeyConfig) {
|
||||
|
||||
|
||||
} else if (showPTTKeyConfig) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 3 - 10, this.width / 2 + 86, height / 3 + 35, 0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 3 - 9, this.width / 2 + 85, height / 3 + 34, 0xFF333333);
|
||||
|
||||
if(showNewPTTKey > 0) {
|
||||
|
||||
if (showNewPTTKey > 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(this.width / 2, height / 3 + 5, 0.0f);
|
||||
GlStateManager.scale(2.0f, 2.0f, 2.0f);
|
||||
drawCenteredString(this.fontRendererObj, Keyboard.getKeyName(mc.gameSettings.voicePTTKey), 0, 0, 0xFFCC11);
|
||||
drawCenteredString(this.fontRendererObj, Keyboard.getKeyName(mc.gameSettings.voicePTTKey), 0, 0,
|
||||
0xFFCC11);
|
||||
GlStateManager.popMatrix();
|
||||
}else {
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.pttChangeDesc"), this.width / 2, height / 3 + 8, 16777215);
|
||||
} else {
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.pttChangeDesc"), this.width / 2,
|
||||
height / 3 + 8, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drawButtons(mx, my, partialTicks);
|
||||
throw new AbortedException();
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
|
||||
GlStateManager.translate(width - 6, 15, 0.0f);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
if(!VoiceClientController.isClientSupported()) {
|
||||
|
||||
if (!VoiceClientController.isClientSupported()) {
|
||||
txt = I18n.format("voice.titleVoiceUnavailable");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 6, 0xFF7777);
|
||||
txt = I18n.format("voice.titleVoiceBrowserError");
|
||||
|
@ -220,8 +245,8 @@ public class GuiVoiceMenu extends Gui {
|
|||
GlStateManager.popMatrix();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!VoiceClientController.isServerSupported()) {
|
||||
|
||||
if (!VoiceClientController.isServerSupported()) {
|
||||
txt = I18n.format("voice.titleNoVoice");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xFF7777);
|
||||
GlStateManager.popMatrix();
|
||||
|
@ -230,29 +255,33 @@ public class GuiVoiceMenu extends Gui {
|
|||
|
||||
int xo = 0;
|
||||
// this feature is optional
|
||||
//if(VoiceClientController.voiceRelayed()) {
|
||||
// txt = I18n.format("voice.warning1");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 8, 0xBB9999);
|
||||
// txt = I18n.format("voice.warning2");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 18, 0xBB9999);
|
||||
// txt = I18n.format("voice.warning3");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 28, 0xBB9999);
|
||||
// xo = 43;
|
||||
// GlStateManager.translate(0.0f, xo, 0.0f);
|
||||
//}
|
||||
|
||||
// if(VoiceClientController.voiceRelayed()) {
|
||||
// txt = I18n.format("voice.warning1");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 8,
|
||||
// 0xBB9999);
|
||||
// txt = I18n.format("voice.warning2");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 18,
|
||||
// 0xBB9999);
|
||||
// txt = I18n.format("voice.warning3");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 28,
|
||||
// 0xBB9999);
|
||||
// xo = 43;
|
||||
// GlStateManager.translate(0.0f, xo, 0.0f);
|
||||
// }
|
||||
|
||||
EnumVoiceChannelStatus status = VoiceClientController.getVoiceStatus();
|
||||
EnumVoiceChannelType channel = VoiceClientController.getVoiceChannel();
|
||||
|
||||
|
||||
boolean flag = false;
|
||||
|
||||
if(channel == EnumVoiceChannelType.NONE) {
|
||||
|
||||
if (channel == EnumVoiceChannelType.NONE) {
|
||||
flag = true;
|
||||
}else {
|
||||
if(status == EnumVoiceChannelStatus.CONNECTED) {
|
||||
|
||||
if(channel == EnumVoiceChannelType.PROXIMITY) {
|
||||
txt = I18n.format("voice.connectedRadius").replace("$radius$", "" + VoiceClientController.getVoiceProximity()).replace("$f$", "");
|
||||
} else {
|
||||
if (status == EnumVoiceChannelStatus.CONNECTED) {
|
||||
|
||||
if (channel == EnumVoiceChannelType.PROXIMITY) {
|
||||
txt = I18n.format("voice.connectedRadius")
|
||||
.replace("$radius$", "" + VoiceClientController.getVoiceProximity()).replace("$f$", "");
|
||||
int w = fontRendererObj.getStringWidth(txt);
|
||||
int xx = width - 5 - (w * 3 / 4);
|
||||
int yy = 15 + (xo * 3 / 4);
|
||||
|
@ -260,63 +289,65 @@ public class GuiVoiceMenu extends Gui {
|
|||
voiceScreenButtonChangeRadiusposY = yy;
|
||||
voiceScreenButtonChangeRadiusposW = width - 3 - xx;
|
||||
voiceScreenButtonChangeRadiusposH = 12;
|
||||
if(mx >= xx && my >= yy && mx < xx + voiceScreenButtonChangeRadiusposW && my < yy + 12) {
|
||||
txt = I18n.format("voice.connectedRadius").replace("$radius$", "" + VoiceClientController.getVoiceProximity())
|
||||
if (mx >= xx && my >= yy && mx < xx + voiceScreenButtonChangeRadiusposW && my < yy + 12) {
|
||||
txt = I18n.format("voice.connectedRadius")
|
||||
.replace("$radius$", "" + VoiceClientController.getVoiceProximity())
|
||||
.replace("$f$", "" + EnumChatFormatting.UNDERLINE) + EnumChatFormatting.RESET;
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
txt = I18n.format("voice.connectedGlobal");
|
||||
}
|
||||
|
||||
|
||||
voiceScreenVolumeIndicatorX = width - 15 - (104 * 3 / 4);
|
||||
voiceScreenVolumeIndicatorY = 15 + (xo * 3 / 4) + 30;
|
||||
voiceScreenVolumeIndicatorW = width - voiceScreenVolumeIndicatorX - 4;
|
||||
voiceScreenVolumeIndicatorH = 23;
|
||||
|
||||
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0x66DD66);
|
||||
|
||||
drawRect(-90, 42, 2, 52, 0xFFAAAAAA);
|
||||
drawRect(-89, 43, 1, 51, 0xFF222222);
|
||||
|
||||
|
||||
float vol = VoiceClientController.getVoiceListenVolume();
|
||||
drawRect(-89, 43, -89 + (int)(vol * 90), 51, 0xFF993322);
|
||||
|
||||
for(float f = 0.07f; f < vol; f += 0.08f) {
|
||||
int ww = (int)(f * 90);
|
||||
drawRect(-89, 43, -89 + (int) (vol * 90), 51, 0xFF993322);
|
||||
|
||||
for (float f = 0.07f; f < vol; f += 0.08f) {
|
||||
int ww = (int) (f * 90);
|
||||
drawRect(-89 + ww, 43, -89 + ww + 1, 51, 0xFF999999);
|
||||
}
|
||||
|
||||
drawRect(-90, 57, 2, 67, 0xFFAAAAAA);
|
||||
drawRect(-89, 58, 1, 66, 0xFF222222);
|
||||
|
||||
|
||||
vol = VoiceClientController.getVoiceSpeakVolume();
|
||||
drawRect(-89, 58, -89 + (int)(vol * 90), 66, 0xFF993322);
|
||||
|
||||
for(float f = 0.07f; f < vol; f += 0.08f) {
|
||||
int ww = (int)(f * 90);
|
||||
drawRect(-89, 58, -89 + (int) (vol * 90), 66, 0xFF993322);
|
||||
|
||||
for (float f = 0.07f; f < vol; f += 0.08f) {
|
||||
int ww = (int) (f * 90);
|
||||
drawRect(-89 + ww, 58, -89 + ww + 1, 66, 0xFF999999);
|
||||
}
|
||||
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
GlStateManager.color(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-104.0f, 41.5f, 0.0f);
|
||||
GlStateManager.scale(0.7f, 0.7f, 0.7f);
|
||||
drawTexturedModalRect(0, 0, 64, 144, 16, 16);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-104.0f, 56.5f, 0.0f);
|
||||
GlStateManager.scale(0.7f, 0.7f, 0.7f);
|
||||
if((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
|
||||
if ((mc.currentScreen == null || !mc.currentScreen.blockPTTKey())
|
||||
&& Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
|
||||
GlStateManager.color(0.9f, 0.4f, 0.4f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 64, 16, 16);
|
||||
}else {
|
||||
} else {
|
||||
drawTexturedModalRect(0, 0, 64, 32, 16, 16);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
txt = I18n.format("voice.ptt", Keyboard.getKeyName(mc.gameSettings.voicePTTKey));
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt) - 10, 76, 0x66DD66);
|
||||
|
||||
|
@ -327,9 +358,9 @@ public class GuiVoiceMenu extends Gui {
|
|||
GlStateManager.scale(0.35f, 0.35f, 0.35f);
|
||||
drawTexturedModalRect(0, 0, 32, 224, 32, 32);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
txt = I18n.format("voice.playersListening");
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0f, 98.0f, 0.0f);
|
||||
GlStateManager.scale(1.2f, 1.2f, 1.2f);
|
||||
|
@ -337,70 +368,73 @@ public class GuiVoiceMenu extends Gui {
|
|||
GlStateManager.popMatrix();
|
||||
|
||||
List<EaglercraftUUID> playersToRender = VoiceClientController.getVoiceRecent();
|
||||
|
||||
if(playersToRender.size() > 0) {
|
||||
|
||||
if (playersToRender.size() > 0) {
|
||||
EaglercraftUUID uuid;
|
||||
Set<EaglercraftUUID> playersSpeaking = VoiceClientController.getVoiceSpeaking();
|
||||
Set<EaglercraftUUID> playersMuted = VoiceClientController.getVoiceMuted();
|
||||
for(int i = 0, l = playersToRender.size(); i < l; ++i) {
|
||||
for (int i = 0, l = playersToRender.size(); i < l; ++i) {
|
||||
uuid = playersToRender.get(i);
|
||||
txt = VoiceClientController.getVoiceUsername(uuid);
|
||||
|
||||
|
||||
boolean muted = playersMuted.contains(uuid);
|
||||
boolean speaking = !muted && playersSpeaking.contains(uuid);
|
||||
|
||||
|
||||
int mhy = voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 33 + i * 9;
|
||||
boolean hovered = mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9;
|
||||
boolean hovered = mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy
|
||||
&& mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9;
|
||||
float cm = hovered ? 1.5f : 1.0f;
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-100.0f, 115.0f + i * 12.0f, 0.0f);
|
||||
GlStateManager.scale(0.78f, 0.78f, 0.78f);
|
||||
|
||||
if(muted) {
|
||||
|
||||
if (muted) {
|
||||
GlStateManager.color(1.0f * cm, 0.2f * cm, 0.2f * cm, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 208, 16, 16);
|
||||
}else if(speaking) {
|
||||
} else if (speaking) {
|
||||
GlStateManager.color(1.0f * cm, 1.0f * cm, 1.0f * cm, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.color(0.65f * cm, 0.65f * cm, 0.65f * cm, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 144, 16, 16);
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(muted) {
|
||||
if (muted) {
|
||||
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0xCC4444, cm));
|
||||
}else if(speaking) {
|
||||
} else if (speaking) {
|
||||
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0xCCCCCC, cm));
|
||||
}else {
|
||||
} else {
|
||||
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0x999999, cm));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
txt = "(none)";
|
||||
drawString(fontRendererObj, txt, -fontRendererObj.getStringWidth(txt), 112, 0xAAAAAA);
|
||||
}
|
||||
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTING) {
|
||||
float fadeTimer = MathHelper.sin((float)((System.currentTimeMillis() % 700l) * 0.0014d) * 3.14159f) * 0.35f + 0.3f;
|
||||
|
||||
} else if (status == EnumVoiceChannelStatus.CONNECTING) {
|
||||
float fadeTimer = MathHelper.sin((float) ((System.currentTimeMillis() % 700l) * 0.0014d) * 3.14159f)
|
||||
* 0.35f + 0.3f;
|
||||
txt = I18n.format("voice.connecting");
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, (0xFFDD77 | ((int)(Math.pow(fadeTimer, 1.0d / 2.2d) * 255.0f) << 24)));
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5,
|
||||
(0xFFDD77 | ((int) (Math.pow(fadeTimer, 1.0d / 2.2d) * 255.0f) << 24)));
|
||||
GlStateManager.disableBlend();
|
||||
}else if(status == EnumVoiceChannelStatus.UNAVAILABLE) {
|
||||
} else if (status == EnumVoiceChannelStatus.UNAVAILABLE) {
|
||||
txt = I18n.format("voice.unavailable");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xFF3333);
|
||||
}else {
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(flag) {
|
||||
|
||||
if (flag) {
|
||||
txt = I18n.format("voice.notConnected");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xBB9999);
|
||||
}
|
||||
|
@ -412,7 +446,7 @@ public class GuiVoiceMenu extends Gui {
|
|||
int OFFwidth = fontRendererObj.getStringWidth(OFFstring);
|
||||
int RADIUSwidth = fontRendererObj.getStringWidth(RADIUSstring);
|
||||
int GLOBALwidth = fontRendererObj.getStringWidth(GLOBALstring);
|
||||
|
||||
|
||||
voiceButtonOFFposX = 0 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth;
|
||||
voiceButtonOFFposY = 20;
|
||||
voiceButtonOFFposW = OFFwidth + 5;
|
||||
|
@ -442,89 +476,111 @@ public class GuiVoiceMenu extends Gui {
|
|||
voiceScreenButtonGLOBALposY = 15 + (voiceButtonGLOBALposY + xo) * 3 / 4;
|
||||
voiceScreenButtonGLOBALposW = voiceButtonGLOBALposW * 3 / 4;
|
||||
voiceScreenButtonGLOBALposH = voiceButtonGLOBALposH * 3 / 4;
|
||||
|
||||
if(channel == EnumVoiceChannelType.NONE) {
|
||||
|
||||
if (channel == EnumVoiceChannelType.NONE) {
|
||||
drawOutline(voiceButtonOFFposX, voiceButtonOFFposY, voiceButtonOFFposW, voiceButtonOFFposH, 0xFFCCCCCC);
|
||||
drawRect(voiceButtonOFFposX + 1, voiceButtonOFFposY + 1, voiceButtonOFFposX + voiceButtonOFFposW - 2,
|
||||
voiceButtonOFFposY + voiceButtonOFFposH - 1, 0xFF222222);
|
||||
}else if(mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
|
||||
} else if (mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
|
||||
voiceScreenButtonOFFposW && my < voiceScreenButtonOFFposY + voiceScreenButtonOFFposH) {
|
||||
drawOutline(voiceButtonOFFposX, voiceButtonOFFposY, voiceButtonOFFposW, voiceButtonOFFposH, 0xFF777777);
|
||||
}
|
||||
|
||||
if(channel == EnumVoiceChannelType.PROXIMITY) {
|
||||
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH, 0xFFCCCCCC);
|
||||
drawRect(voiceButtonRADIUSposX + 1, voiceButtonRADIUSposY + 1, voiceButtonRADIUSposX + voiceButtonRADIUSposW - 2,
|
||||
if (channel == EnumVoiceChannelType.PROXIMITY) {
|
||||
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH,
|
||||
0xFFCCCCCC);
|
||||
drawRect(voiceButtonRADIUSposX + 1, voiceButtonRADIUSposY + 1,
|
||||
voiceButtonRADIUSposX + voiceButtonRADIUSposW - 2,
|
||||
voiceButtonRADIUSposY + voiceButtonRADIUSposH - 1, 0xFF222222);
|
||||
}else if(mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY && mx < voiceScreenButtonRADIUSposX +
|
||||
voiceScreenButtonRADIUSposW && my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
|
||||
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH, 0xFF777777);
|
||||
} else if (mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY
|
||||
&& mx < voiceScreenButtonRADIUSposX +
|
||||
voiceScreenButtonRADIUSposW
|
||||
&& my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
|
||||
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH,
|
||||
0xFF777777);
|
||||
}
|
||||
|
||||
if(channel == EnumVoiceChannelType.GLOBAL) {
|
||||
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH, 0xFFCCCCCC);
|
||||
drawRect(voiceButtonGLOBALposX + 1, voiceButtonGLOBALposY + 1, voiceButtonGLOBALposX + voiceButtonGLOBALposW - 2,
|
||||
if (channel == EnumVoiceChannelType.GLOBAL) {
|
||||
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH,
|
||||
0xFFCCCCCC);
|
||||
drawRect(voiceButtonGLOBALposX + 1, voiceButtonGLOBALposY + 1,
|
||||
voiceButtonGLOBALposX + voiceButtonGLOBALposW - 2,
|
||||
voiceButtonGLOBALposY + voiceButtonGLOBALposH - 1, 0xFF222222);
|
||||
}else if(mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY && mx < voiceScreenButtonGLOBALposX +
|
||||
voiceScreenButtonGLOBALposW && my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
|
||||
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH, 0xFF777777);
|
||||
} else if (mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY
|
||||
&& mx < voiceScreenButtonGLOBALposX +
|
||||
voiceScreenButtonGLOBALposW
|
||||
&& my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
|
||||
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH,
|
||||
0xFF777777);
|
||||
}
|
||||
|
||||
int enabledColor = (status == EnumVoiceChannelStatus.CONNECTED || channel == EnumVoiceChannelType.NONE) ? 0x66DD66 : 0xDDCC66;
|
||||
int enabledColor = (status == EnumVoiceChannelStatus.CONNECTED || channel == EnumVoiceChannelType.NONE)
|
||||
? 0x66DD66
|
||||
: 0xDDCC66;
|
||||
int disabledColor = 0xDD4444;
|
||||
|
||||
if(channel != EnumVoiceChannelType.NONE && status == EnumVoiceChannelStatus.UNAVAILABLE) {
|
||||
|
||||
if (channel != EnumVoiceChannelType.NONE && status == EnumVoiceChannelStatus.UNAVAILABLE) {
|
||||
enabledColor = disabledColor;
|
||||
}
|
||||
|
||||
drawString(fontRendererObj, OFFstring, 3 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth, 24, channel == EnumVoiceChannelType.NONE ? enabledColor : disabledColor);
|
||||
drawString(fontRendererObj, RADIUSstring, 3 - RADIUSwidth - 8 - GLOBALwidth, 24, channel == EnumVoiceChannelType.PROXIMITY ? enabledColor : disabledColor);
|
||||
drawString(fontRendererObj, GLOBALstring, 3 - GLOBALwidth, 24, channel == EnumVoiceChannelType.GLOBAL ? enabledColor : disabledColor);
|
||||
|
||||
|
||||
drawString(fontRendererObj, OFFstring, 3 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth, 24,
|
||||
channel == EnumVoiceChannelType.NONE ? enabledColor : disabledColor);
|
||||
drawString(fontRendererObj, RADIUSstring, 3 - RADIUSwidth - 8 - GLOBALwidth, 24,
|
||||
channel == EnumVoiceChannelType.PROXIMITY ? enabledColor : disabledColor);
|
||||
drawString(fontRendererObj, GLOBALstring, 3 - GLOBALwidth, 24,
|
||||
channel == EnumVoiceChannelType.GLOBAL ? enabledColor : disabledColor);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(showingCompatWarning) {
|
||||
|
||||
drawNotice(I18n.format("voice.unsupportedWarning1"), false, I18n.format("voice.unsupportedWarning2"), I18n.format("voice.unsupportedWarning3"),
|
||||
"", I18n.format("voice.unsupportedWarning4"), I18n.format("voice.unsupportedWarning5"), I18n.format("voice.unsupportedWarning6"),
|
||||
I18n.format("voice.unsupportedWarning7"), I18n.format("voice.unsupportedWarning8"), I18n.format("voice.unsupportedWarning9"));
|
||||
|
||||
|
||||
if (showingCompatWarning) {
|
||||
|
||||
drawNotice(I18n.format("voice.unsupportedWarning1"), false, I18n.format("voice.unsupportedWarning2"),
|
||||
I18n.format("voice.unsupportedWarning3"),
|
||||
"", I18n.format("voice.unsupportedWarning4"), I18n.format("voice.unsupportedWarning5"),
|
||||
I18n.format("voice.unsupportedWarning6"),
|
||||
I18n.format("voice.unsupportedWarning7"), I18n.format("voice.unsupportedWarning8"),
|
||||
I18n.format("voice.unsupportedWarning9"));
|
||||
|
||||
noticeContinueButton.visible = true;
|
||||
noticeCancelButton.visible = false;
|
||||
}else if(showingTrackingWarning) {
|
||||
|
||||
drawNotice(I18n.format("voice.ipGrabWarning1"), true, I18n.format("voice.ipGrabWarning2"), I18n.format("voice.ipGrabWarning3"),
|
||||
I18n.format("voice.ipGrabWarning4"), "", I18n.format("voice.ipGrabWarning5"), I18n.format("voice.ipGrabWarning6"),
|
||||
I18n.format("voice.ipGrabWarning7"), I18n.format("voice.ipGrabWarning8"), I18n.format("voice.ipGrabWarning9"),
|
||||
I18n.format("voice.ipGrabWarning10"), I18n.format("voice.ipGrabWarning11"), I18n.format("voice.ipGrabWarning12"));
|
||||
|
||||
} else if (showingTrackingWarning) {
|
||||
|
||||
drawNotice(I18n.format("voice.ipGrabWarning1"), true, I18n.format("voice.ipGrabWarning2"),
|
||||
I18n.format("voice.ipGrabWarning3"),
|
||||
I18n.format("voice.ipGrabWarning4"), "", I18n.format("voice.ipGrabWarning5"),
|
||||
I18n.format("voice.ipGrabWarning6"),
|
||||
I18n.format("voice.ipGrabWarning7"), I18n.format("voice.ipGrabWarning8"),
|
||||
I18n.format("voice.ipGrabWarning9"),
|
||||
I18n.format("voice.ipGrabWarning10"), I18n.format("voice.ipGrabWarning11"),
|
||||
I18n.format("voice.ipGrabWarning12"));
|
||||
|
||||
noticeContinueButton.visible = true;
|
||||
noticeCancelButton.visible = true;
|
||||
}else {
|
||||
} else {
|
||||
noticeContinueButton.visible = false;
|
||||
noticeCancelButton.visible = false;
|
||||
}
|
||||
|
||||
|
||||
drawButtons(mx, my, partialTicks);
|
||||
|
||||
if(showingCompatWarning || showingTrackingWarning) {
|
||||
if (showingCompatWarning || showingTrackingWarning) {
|
||||
throw new AbortedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void drawNotice(String title, boolean showCancel, String... lines) {
|
||||
|
||||
|
||||
int widthAccum = 0;
|
||||
|
||||
for(int i = 0; i < lines.length; ++i) {
|
||||
|
||||
for (int i = 0; i < lines.length; ++i) {
|
||||
int w = fontRendererObj.getStringWidth(lines[i]);
|
||||
if(widthAccum < w) {
|
||||
if (widthAccum < w) {
|
||||
widthAccum = w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int margin = 15;
|
||||
|
||||
|
||||
int x = (width - widthAccum) / 2;
|
||||
int y = (height - lines.length * 10 - 60 - margin) / 2;
|
||||
|
||||
|
@ -532,18 +588,18 @@ public class GuiVoiceMenu extends Gui {
|
|||
y + lines.length * 10 + 49 + margin, 0xFFCCCCCC);
|
||||
drawRect(x - margin, y - margin, x + widthAccum + margin,
|
||||
y + lines.length * 10 + 48 + margin, 0xFF111111);
|
||||
|
||||
|
||||
drawCenteredString(fontRendererObj, EnumChatFormatting.BOLD + title, width / 2, y, 0xFF7766);
|
||||
|
||||
for(int i = 0; i < lines.length; ++i) {
|
||||
|
||||
for (int i = 0; i < lines.length; ++i) {
|
||||
drawString(fontRendererObj, lines[i], x, y + i * 10 + 18, 0xDDAAAA);
|
||||
}
|
||||
|
||||
if(!showCancel) {
|
||||
|
||||
if (!showCancel) {
|
||||
noticeContinueButton.width = 150;
|
||||
noticeContinueButton.xPosition = (width - 150) / 2;
|
||||
noticeContinueButton.yPosition = y + lines.length * 10 + 29;
|
||||
}else {
|
||||
} else {
|
||||
noticeContinueButton.width = widthAccum / 2 - 10;
|
||||
noticeContinueButton.xPosition = (width - widthAccum) / 2 + widthAccum / 2 + 3;
|
||||
noticeContinueButton.yPosition = y + lines.length * 10 + 28;
|
||||
|
@ -551,13 +607,13 @@ public class GuiVoiceMenu extends Gui {
|
|||
noticeCancelButton.xPosition = (width - widthAccum) / 2 + 4;
|
||||
noticeCancelButton.yPosition = y + lines.length * 10 + 28;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static int attenuate(int cin, float f) {
|
||||
return attenuate(cin, f, f, f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
public static int attenuate(int cin, float r, float g, float b, float a) {
|
||||
float var10 = (float) (cin >> 24 & 255) / 255.0F;
|
||||
float var6 = (float) (cin >> 16 & 255) / 255.0F;
|
||||
|
@ -567,40 +623,41 @@ public class GuiVoiceMenu extends Gui {
|
|||
var6 *= r;
|
||||
var7 *= g;
|
||||
var8 *= b;
|
||||
if(var10 > 1.0f) {
|
||||
if (var10 > 1.0f) {
|
||||
var10 = 1.0f;
|
||||
}
|
||||
if(var6 > 1.0f) {
|
||||
if (var6 > 1.0f) {
|
||||
var6 = 1.0f;
|
||||
}
|
||||
if(var7 > 1.0f) {
|
||||
if (var7 > 1.0f) {
|
||||
var7 = 1.0f;
|
||||
}
|
||||
if(var8 > 1.0f) {
|
||||
if (var8 > 1.0f) {
|
||||
var8 = 1.0f;
|
||||
}
|
||||
return (((int)(var10 * 255.0f) << 24) | ((int)(var6 * 255.0f) << 16) | ((int)(var7 * 255.0f) << 8) | (int)(var8 * 255.0f));
|
||||
return (((int) (var10 * 255.0f) << 24) | ((int) (var6 * 255.0f) << 16) | ((int) (var7 * 255.0f) << 8)
|
||||
| (int) (var8 * 255.0f));
|
||||
}
|
||||
|
||||
|
||||
private void drawOutline(int x, int y, int w, int h, int color) {
|
||||
drawRect(x, y, x + w, y + 1, color);
|
||||
drawRect(x + w - 1, y + 1, x + w, y + h - 1, color);
|
||||
drawRect(x, y + h - 1, x + w, y + h, color);
|
||||
drawRect(x, y + 1, x + 1, y + h - 1, color);
|
||||
}
|
||||
|
||||
|
||||
public void mouseReleased(int par1, int par2, int par3) {
|
||||
applyRadiusButton.mouseReleased(par1, par2);
|
||||
applyVolumeButton.mouseReleased(par1, par2);
|
||||
noticeContinueButton.mouseReleased(par1, par2);
|
||||
noticeCancelButton.mouseReleased(par1, par2);
|
||||
if(showSliderBlocks || showSliderVolume) {
|
||||
if(showSliderBlocks) {
|
||||
if(par3 == 0) {
|
||||
if (showSliderBlocks || showSliderVolume) {
|
||||
if (showSliderBlocks) {
|
||||
if (par3 == 0) {
|
||||
sliderBlocks.mouseReleased(par1, par2);
|
||||
}
|
||||
}else if(showSliderVolume) {
|
||||
if(par3 == 0) {
|
||||
} else if (showSliderVolume) {
|
||||
if (par3 == 0) {
|
||||
sliderListenVolume.mouseReleased(par1, par2);
|
||||
sliderSpeakVolume.mouseReleased(par1, par2);
|
||||
}
|
||||
|
@ -608,13 +665,13 @@ public class GuiVoiceMenu extends Gui {
|
|||
throw new AbortedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void keyTyped(char par1, int par2) {
|
||||
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
|
||||
if(showPTTKeyConfig) {
|
||||
if(par2 == 1) {
|
||||
if (showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
|
||||
if (showPTTKeyConfig) {
|
||||
if (par2 == 1) {
|
||||
showPTTKeyConfig = false;
|
||||
}else {
|
||||
} else {
|
||||
mc.gameSettings.voicePTTKey = par2;
|
||||
showNewPTTKey = 10;
|
||||
}
|
||||
|
@ -622,94 +679,119 @@ public class GuiVoiceMenu extends Gui {
|
|||
throw new AbortedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void mouseClicked(int mx, int my, int button) {
|
||||
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning || showingTrackingWarning) {
|
||||
if(showSliderBlocks) {
|
||||
if (showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning
|
||||
|| showingTrackingWarning) {
|
||||
if (showSliderBlocks) {
|
||||
sliderBlocks.mousePressed(mc, mx, my);
|
||||
}else if(showSliderVolume) {
|
||||
} else if (showSliderVolume) {
|
||||
sliderListenVolume.mousePressed(mc, mx, my);
|
||||
sliderSpeakVolume.mousePressed(mc, mx, my);
|
||||
}
|
||||
if(button == 0) {
|
||||
if(applyRadiusButton.mousePressed(mc, mx, my)) actionPerformed(applyRadiusButton);
|
||||
if(applyVolumeButton.mousePressed(mc, mx, my)) actionPerformed(applyVolumeButton);
|
||||
if(noticeContinueButton.mousePressed(mc, mx, my)) actionPerformed(noticeContinueButton);
|
||||
if(noticeCancelButton.mousePressed(mc, mx, my)) actionPerformed(noticeCancelButton);
|
||||
if (button == 0) {
|
||||
if (applyRadiusButton.mousePressed(mc, mx, my))
|
||||
actionPerformed(applyRadiusButton);
|
||||
if (applyVolumeButton.mousePressed(mc, mx, my))
|
||||
actionPerformed(applyVolumeButton);
|
||||
if (noticeContinueButton.mousePressed(mc, mx, my))
|
||||
actionPerformed(noticeContinueButton);
|
||||
if (noticeCancelButton.mousePressed(mc, mx, my))
|
||||
actionPerformed(noticeCancelButton);
|
||||
}
|
||||
throw new AbortedException();
|
||||
}
|
||||
|
||||
|
||||
EnumVoiceChannelStatus status = VoiceClientController.getVoiceStatus();
|
||||
EnumVoiceChannelType channel = VoiceClientController.getVoiceChannel();
|
||||
|
||||
if(button == 0) {
|
||||
if(VoiceClientController.isSupported()) {
|
||||
if(mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
|
||||
|
||||
if (button == 0) {
|
||||
if (VoiceClientController.isSupported()) {
|
||||
if (mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
|
||||
voiceScreenButtonOFFposW && my < voiceScreenButtonOFFposY + voiceScreenButtonOFFposH) {
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY && mx < voiceScreenButtonRADIUSposX +
|
||||
voiceScreenButtonRADIUSposW && my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
|
||||
|
||||
if(showCompatWarning) {
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
} else if (mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY
|
||||
&& mx < voiceScreenButtonRADIUSposX +
|
||||
voiceScreenButtonRADIUSposW
|
||||
&& my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
|
||||
|
||||
if (showCompatWarning) {
|
||||
continueChannel = EnumVoiceChannelType.PROXIMITY;
|
||||
showingCompatWarning = true;
|
||||
}else if(showTrackingWarning) {
|
||||
} else if (showTrackingWarning) {
|
||||
continueChannel = EnumVoiceChannelType.PROXIMITY;
|
||||
showingTrackingWarning = true;
|
||||
}else {
|
||||
} else {
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.PROXIMITY);
|
||||
}
|
||||
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
|
||||
}else if(mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY && mx < voiceScreenButtonGLOBALposX +
|
||||
voiceScreenButtonGLOBALposW && my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
|
||||
|
||||
if(showCompatWarning) {
|
||||
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
|
||||
} else if (mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY
|
||||
&& mx < voiceScreenButtonGLOBALposX +
|
||||
voiceScreenButtonGLOBALposW
|
||||
&& my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
|
||||
|
||||
if (showCompatWarning) {
|
||||
continueChannel = EnumVoiceChannelType.GLOBAL;
|
||||
showingCompatWarning = true;
|
||||
}else if(showTrackingWarning) {
|
||||
} else if (showTrackingWarning) {
|
||||
continueChannel = EnumVoiceChannelType.GLOBAL;
|
||||
showingTrackingWarning = true;
|
||||
}else {
|
||||
} else {
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.GLOBAL);
|
||||
}
|
||||
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(channel == EnumVoiceChannelType.PROXIMITY && status == EnumVoiceChannelStatus.CONNECTED && mx >= voiceScreenButtonChangeRadiusposX &&
|
||||
my >= voiceScreenButtonChangeRadiusposY && mx < voiceScreenButtonChangeRadiusposX + voiceScreenButtonChangeRadiusposW &&
|
||||
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
} else if (channel == EnumVoiceChannelType.PROXIMITY && status == EnumVoiceChannelStatus.CONNECTED
|
||||
&& mx >= voiceScreenButtonChangeRadiusposX &&
|
||||
my >= voiceScreenButtonChangeRadiusposY
|
||||
&& mx < voiceScreenButtonChangeRadiusposX + voiceScreenButtonChangeRadiusposW &&
|
||||
my < voiceScreenButtonChangeRadiusposY + voiceScreenButtonChangeRadiusposH) {
|
||||
showSliderBlocks = true;
|
||||
sliderBlocks.sliderValue = (VoiceClientController.getVoiceProximity() - 5) / 17.0f;
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE && mx >= voiceScreenVolumeIndicatorX &&
|
||||
my >= voiceScreenVolumeIndicatorY && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW &&
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
} else if (status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE
|
||||
&& mx >= voiceScreenVolumeIndicatorX &&
|
||||
my >= voiceScreenVolumeIndicatorY
|
||||
&& mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW &&
|
||||
my < voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH) {
|
||||
showSliderVolume = true;
|
||||
sliderListenVolume.sliderValue = VoiceClientController.getVoiceListenVolume();
|
||||
sliderSpeakVolume.sliderValue = VoiceClientController.getVoiceSpeakVolume();
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE && mx >= voiceScreenVolumeIndicatorX - 1 &&
|
||||
my >= voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 2 && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 &&
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
} else if (status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE
|
||||
&& mx >= voiceScreenVolumeIndicatorX - 1 &&
|
||||
my >= voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 2
|
||||
&& mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 &&
|
||||
my < voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 12) {
|
||||
showPTTKeyConfig = true;
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTED) {
|
||||
this.mc.getSoundHandler()
|
||||
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
} else if (status == EnumVoiceChannelStatus.CONNECTED) {
|
||||
List<EaglercraftUUID> playersToRender = VoiceClientController.getVoiceRecent();
|
||||
if(playersToRender.size() > 0) {
|
||||
if (playersToRender.size() > 0) {
|
||||
Set<EaglercraftUUID> playersMuted = VoiceClientController.getVoiceMuted();
|
||||
for(int i = 0, l = playersToRender.size(); i < l; ++i) {
|
||||
for (int i = 0, l = playersToRender.size(); i < l; ++i) {
|
||||
EaglercraftUUID uuid = playersToRender.get(i);
|
||||
String txt = VoiceClientController.getVoiceUsername(uuid);
|
||||
boolean muted = playersMuted.contains(uuid);
|
||||
int mhy = voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 33 + i * 9;
|
||||
if(mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9) {
|
||||
if (mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy
|
||||
&& mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2
|
||||
&& my < mhy + 9) {
|
||||
VoiceClientController.setVoiceMuted(uuid, !muted);
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
this.mc.getSoundHandler().playSound(
|
||||
PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -717,48 +799,50 @@ public class GuiVoiceMenu extends Gui {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void actionPerformed(GuiButton btn) {
|
||||
if(btn.id == 2) {
|
||||
if (btn.id == 2) {
|
||||
showSliderBlocks = false;
|
||||
VoiceClientController.setVoiceProximity(mc.gameSettings.voiceListenRadius = (int)((sliderBlocks.sliderValue * 17.0f) + 5.0f));
|
||||
VoiceClientController.setVoiceProximity(
|
||||
mc.gameSettings.voiceListenRadius = (int) ((sliderBlocks.sliderValue * 17.0f) + 5.0f));
|
||||
mc.gameSettings.saveOptions();
|
||||
}else if(btn.id == 3) {
|
||||
} else if (btn.id == 3) {
|
||||
showSliderVolume = false;
|
||||
VoiceClientController.setVoiceListenVolume(mc.gameSettings.voiceListenVolume = sliderListenVolume.sliderValue);
|
||||
VoiceClientController
|
||||
.setVoiceListenVolume(mc.gameSettings.voiceListenVolume = sliderListenVolume.sliderValue);
|
||||
VoiceClientController.setVoiceSpeakVolume(mc.gameSettings.voiceSpeakVolume = sliderSpeakVolume.sliderValue);
|
||||
mc.gameSettings.saveOptions();
|
||||
}else if(btn.id == 4) {
|
||||
} else if (btn.id == 4) {
|
||||
showPTTKeyConfig = false;
|
||||
mc.gameSettings.saveOptions();
|
||||
}else if(btn.id == 5) {
|
||||
if(showingCompatWarning) {
|
||||
} else if (btn.id == 5) {
|
||||
if (showingCompatWarning) {
|
||||
showingCompatWarning = false;
|
||||
showCompatWarning = false;
|
||||
if(showTrackingWarning) {
|
||||
if (showTrackingWarning) {
|
||||
showingTrackingWarning = true;
|
||||
}else {
|
||||
} else {
|
||||
VoiceClientController.setVoiceChannel(continueChannel);
|
||||
}
|
||||
}else if(showingTrackingWarning) {
|
||||
} else if (showingTrackingWarning) {
|
||||
showingTrackingWarning = false;
|
||||
showTrackingWarning = false;
|
||||
VoiceClientController.setVoiceChannel(continueChannel);
|
||||
}
|
||||
}else if(btn.id == 6) {
|
||||
if(showingTrackingWarning) {
|
||||
} else if (btn.id == 6) {
|
||||
if (showingTrackingWarning) {
|
||||
showingTrackingWarning = false;
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateScreen() {
|
||||
if(showNewPTTKey > 0) {
|
||||
if (showNewPTTKey > 0) {
|
||||
--showNewPTTKey;
|
||||
if(showNewPTTKey == 0) {
|
||||
if (showNewPTTKey == 0) {
|
||||
showPTTKeyConfig = false;
|
||||
mc.gameSettings.saveOptions();
|
||||
}
|
||||
|
@ -766,7 +850,8 @@ public class GuiVoiceMenu extends Gui {
|
|||
}
|
||||
|
||||
public boolean isBlockingInput() {
|
||||
return showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning || showingTrackingWarning;
|
||||
return showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning
|
||||
|| showingTrackingWarning;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,16 +16,24 @@ import net.minecraft.client.gui.GuiIngameMenu;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -35,71 +43,73 @@ public class GuiVoiceOverlay extends Gui {
|
|||
public final Minecraft mc;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
|
||||
private long pttTimer = 0l;
|
||||
|
||||
|
||||
public GuiVoiceOverlay(Minecraft mc) {
|
||||
this.mc = mc;
|
||||
}
|
||||
|
||||
|
||||
public void setResolution(int w, int h) {
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
}
|
||||
|
||||
|
||||
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
|
||||
|
||||
public void drawOverlay() {
|
||||
if(mc.theWorld != null && VoiceClientController.getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED && VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.NONE &&
|
||||
if (mc.theWorld != null && VoiceClientController.getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED
|
||||
&& VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.NONE &&
|
||||
!(mc.currentScreen != null && (mc.currentScreen instanceof GuiIngameMenu))) {
|
||||
|
||||
if(mc.currentScreen != null && mc.currentScreen.doesGuiPauseGame()) {
|
||||
|
||||
if (mc.currentScreen != null && mc.currentScreen.doesGuiPauseGame()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.alphaFunc(GL_GREATER, 0.1F);
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
if(mc.currentScreen == null || (mc.currentScreen instanceof GuiChat)) {
|
||||
|
||||
if (mc.currentScreen == null || (mc.currentScreen instanceof GuiChat)) {
|
||||
GlStateManager.translate(width / 2 + 77, height - 56, 0.0f);
|
||||
if(mc.thePlayer == null || mc.thePlayer.capabilities.isCreativeMode) {
|
||||
if (mc.thePlayer == null || mc.thePlayer.capabilities.isCreativeMode) {
|
||||
GlStateManager.translate(0.0f, 16.0f, 0.0f);
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.translate(width / 2 + 10, 4, 0.0f);
|
||||
}
|
||||
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
|
||||
String txxt = "press '" + Keyboard.getKeyName(mc.gameSettings.voicePTTKey) + "'";
|
||||
drawString(mc.fontRendererObj, txxt, -3 - mc.fontRendererObj.getStringWidth(txxt), 9, 0xDDDDDD);
|
||||
|
||||
GlStateManager.scale(0.66f, 0.66f, 0.66f);
|
||||
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
if((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
|
||||
|
||||
if ((mc.currentScreen == null || !mc.currentScreen.blockPTTKey())
|
||||
&& Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(pttTimer == 0l) {
|
||||
if (pttTimer == 0l) {
|
||||
pttTimer = millis;
|
||||
}
|
||||
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 64, 32, 32);
|
||||
GlStateManager.translate(-1.5f, -1.5f, 0.0f);
|
||||
if(millis - pttTimer < 1050l) {
|
||||
if((millis - pttTimer) % 300l < 150l) {
|
||||
if (millis - pttTimer < 1050l) {
|
||||
if ((millis - pttTimer) % 300l < 150l) {
|
||||
GlStateManager.color(0.9f, 0.2f, 0.2f, 1.0f);
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.color(0.9f, 0.7f, 0.7f, 1.0f);
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.color(0.9f, 0.3f, 0.3f, 1.0f);
|
||||
}
|
||||
drawTexturedModalRect(0, 0, 0, 64, 32, 32);
|
||||
}else {
|
||||
} else {
|
||||
pttTimer = 0l;
|
||||
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
|
||||
|
@ -109,55 +119,55 @@ public class GuiVoiceOverlay extends Gui {
|
|||
GlStateManager.translate(-0.5f, -0.5f, 0.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) {
|
||||
|
||||
if (VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) {
|
||||
Set<EaglercraftUUID> listeners = VoiceClientController.getVoiceListening();
|
||||
if(listeners.size() > 0) {
|
||||
if (listeners.size() > 0) {
|
||||
Set<EaglercraftUUID> speakers = VoiceClientController.getVoiceSpeaking();
|
||||
Set<EaglercraftUUID> muted = VoiceClientController.getVoiceMuted();
|
||||
|
||||
|
||||
List<EaglercraftUUID> listenerList = new ArrayList();
|
||||
listenerList.addAll(listeners);
|
||||
listenerList.removeAll(muted);
|
||||
|
||||
while(listenerList.size() > 5) {
|
||||
|
||||
while (listenerList.size() > 5) {
|
||||
boolean flag = false;
|
||||
for(int i = 0, l = listenerList.size(); i < l; ++i) {
|
||||
if(!speakers.contains(listenerList.get(i))) {
|
||||
for (int i = 0, l = listenerList.size(); i < l; ++i) {
|
||||
if (!speakers.contains(listenerList.get(i))) {
|
||||
listenerList.remove(i);
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!flag) {
|
||||
if (!flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int more = listenerList.size() - 5;
|
||||
|
||||
|
||||
int ww = width;
|
||||
int hh = height;
|
||||
|
||||
if(mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
|
||||
|
||||
if (mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
|
||||
hh -= 15;
|
||||
}
|
||||
|
||||
|
||||
List<String> listenerListStr = new ArrayList(Math.min(5, listenerList.size()));
|
||||
|
||||
|
||||
int left = 50;
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
for (int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
String txt = VoiceClientController.getVoiceUsername(listenerList.get(i));
|
||||
listenerListStr.add(txt);
|
||||
int j = mc.fontRendererObj.getStringWidth(txt) + 4;
|
||||
if(j > left) {
|
||||
if (j > left) {
|
||||
left = j;
|
||||
}
|
||||
}
|
||||
|
||||
if(more > 0) {
|
||||
|
||||
if (more > 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left + 3, hh - 10, left);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
@ -165,63 +175,64 @@ public class GuiVoiceOverlay extends Gui {
|
|||
GlStateManager.popMatrix();
|
||||
hh -= 9;
|
||||
}
|
||||
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
|
||||
for (int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
boolean speaking = speakers.contains(listenerList.get(i));
|
||||
float speakf = speaking ? 1.0f : 0.75f;
|
||||
|
||||
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11, speaking ? 0xEEEEEE : 0xBBBBBB);
|
||||
|
||||
|
||||
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11,
|
||||
speaking ? 0xEEEEEE : 0xBBBBBB);
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left - 14, hh - 14 - i * 11, 0.0f);
|
||||
|
||||
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
GlStateManager.color(speakf * 0.2f, speakf * 0.2f, speakf * 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
|
||||
GlStateManager.translate(0.25f, 0.25f, 0.0f);
|
||||
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
|
||||
|
||||
|
||||
GlStateManager.translate(-1.25f, -1.25f, 0.0f);
|
||||
GlStateManager.color(speakf, speakf, speakf, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}else if(VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.GLOBAL) {
|
||||
} else if (VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.GLOBAL) {
|
||||
Set<EaglercraftUUID> speakers = VoiceClientController.getVoiceSpeaking();
|
||||
Set<EaglercraftUUID> muted = VoiceClientController.getVoiceMuted();
|
||||
|
||||
|
||||
List<EaglercraftUUID> listenerList = new ArrayList();
|
||||
listenerList.addAll(speakers);
|
||||
listenerList.removeAll(muted);
|
||||
|
||||
|
||||
int more = listenerList.size() - 5;
|
||||
|
||||
|
||||
int ww = width;
|
||||
int hh = height;
|
||||
|
||||
if(mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
|
||||
|
||||
if (mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
|
||||
hh -= 15;
|
||||
}
|
||||
|
||||
|
||||
List<String> listenerListStr = new ArrayList(Math.min(5, listenerList.size()));
|
||||
|
||||
|
||||
int left = 50;
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
for (int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
String txt = VoiceClientController.getVoiceUsername(listenerList.get(i));
|
||||
listenerListStr.add(txt);
|
||||
int j = mc.fontRendererObj.getStringWidth(txt) + 4;
|
||||
if(j > left) {
|
||||
if (j > left) {
|
||||
left = j;
|
||||
}
|
||||
}
|
||||
|
||||
if(more > 0) {
|
||||
|
||||
if (more > 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left + 3, hh - 10, left);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
@ -229,27 +240,27 @@ public class GuiVoiceOverlay extends Gui {
|
|||
GlStateManager.popMatrix();
|
||||
hh -= 9;
|
||||
}
|
||||
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
|
||||
for (int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11, 0xEEEEEE);
|
||||
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left - 14, hh - 14 - i * 11, 0.0f);
|
||||
|
||||
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
GlStateManager.translate(0.25f, 0.25f, 0.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
|
||||
|
||||
GlStateManager.translate(-1.25f, -1.25f, 0.0f);
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,16 +21,24 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -74,7 +82,8 @@ public class VoiceClientController {
|
|||
public static void initializeVoiceClient(Consumer<PacketBuffer> signalSendCallbackIn) {
|
||||
packetSendCallback = signalSendCallbackIn;
|
||||
uuidToNameLookup.clear();
|
||||
if (getVoiceChannel() != EnumVoiceChannelType.NONE) sendInitialVoice();
|
||||
if (getVoiceChannel() != EnumVoiceChannelType.NONE)
|
||||
sendInitialVoice();
|
||||
}
|
||||
|
||||
public static void handleVoiceSignalPacket(PacketBuffer packetData) {
|
||||
|
@ -84,7 +93,7 @@ public class VoiceClientController {
|
|||
static void handleVoiceSignalPacketTypeGlobal(EaglercraftUUID[] voicePlayers, String[] voiceNames) {
|
||||
uuidToNameLookup.clear();
|
||||
for (int i = 0; i < voicePlayers.length; i++) {
|
||||
if(voiceNames != null) {
|
||||
if (voiceNames != null) {
|
||||
uuidToNameLookup.put(voicePlayers[i], voiceNames[i]);
|
||||
}
|
||||
sendPacketRequestIfNeeded(voicePlayers[i]);
|
||||
|
@ -92,7 +101,8 @@ public class VoiceClientController {
|
|||
}
|
||||
|
||||
public static void handleServerDisconnect() {
|
||||
if(!isClientSupported()) return;
|
||||
if (!isClientSupported())
|
||||
return;
|
||||
serverSupport = false;
|
||||
uuidToNameLookup.clear();
|
||||
for (EaglercraftUUID uuid : nearbyPlayers) {
|
||||
|
@ -113,10 +123,10 @@ public class VoiceClientController {
|
|||
static void handleVoiceSignalPacketTypeAllowed(boolean voiceAvailableStat, String[] servs) {
|
||||
serverSupport = voiceAvailableStat;
|
||||
PlatformVoiceClient.setICEServers(servs);
|
||||
if(isSupported()) {
|
||||
if (isSupported()) {
|
||||
EnumVoiceChannelType ch = getVoiceChannel();
|
||||
setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
setVoiceChannel(ch);
|
||||
setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
setVoiceChannel(ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,22 +151,30 @@ public class VoiceClientController {
|
|||
}
|
||||
|
||||
public static void tickVoiceClient(Minecraft mc) {
|
||||
if(!isClientSupported()) return;
|
||||
if (!isClientSupported())
|
||||
return;
|
||||
recentlyNearbyPlayers.checkForExpirations();
|
||||
speakingSet.clear();
|
||||
PlatformVoiceClient.tickVoiceClient();
|
||||
|
||||
if (getVoiceChannel() != EnumVoiceChannelType.NONE && (getVoiceStatus() == EnumVoiceChannelStatus.CONNECTING || getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED)) {
|
||||
activateVoice((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey));
|
||||
if (getVoiceChannel() != EnumVoiceChannelType.NONE && (getVoiceStatus() == EnumVoiceChannelStatus.CONNECTING
|
||||
|| getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED)) {
|
||||
activateVoice((mc.currentScreen == null || !mc.currentScreen.blockPTTKey())
|
||||
&& Keyboard.isKeyDown(mc.gameSettings.voicePTTKey));
|
||||
|
||||
if (mc.theWorld != null && mc.thePlayer != null) {
|
||||
HashSet<EaglercraftUUID> seenPlayers = new HashSet<>();
|
||||
for (EntityPlayer player : mc.theWorld.playerEntities) {
|
||||
if (player == mc.thePlayer) continue;
|
||||
if (getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) updateVoicePosition(player.getUniqueID(), player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
if (player == mc.thePlayer)
|
||||
continue;
|
||||
if (getVoiceChannel() == EnumVoiceChannelType.PROXIMITY)
|
||||
updateVoicePosition(player.getUniqueID(), player.posX, player.posY + player.getEyeHeight(),
|
||||
player.posZ);
|
||||
int prox = 22;
|
||||
// cube
|
||||
if (Math.abs(mc.thePlayer.posX - player.posX) <= prox && Math.abs(mc.thePlayer.posY - player.posY) <= prox && Math.abs(mc.thePlayer.posZ - player.posZ) <= prox) {
|
||||
if (Math.abs(mc.thePlayer.posX - player.posX) <= prox
|
||||
&& Math.abs(mc.thePlayer.posY - player.posY) <= prox
|
||||
&& Math.abs(mc.thePlayer.posZ - player.posZ) <= prox) {
|
||||
if (!uuidToNameLookup.containsKey(player.getUniqueID())) {
|
||||
uuidToNameLookup.put(player.getUniqueID(), player.getName());
|
||||
}
|
||||
|
@ -181,13 +199,17 @@ public class VoiceClientController {
|
|||
|
||||
public static final void removeNearbyPlayer(EaglercraftUUID uuid) {
|
||||
if (nearbyPlayers.remove(uuid)) {
|
||||
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED || getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE) return;
|
||||
if (voiceChannel == EnumVoiceChannelType.PROXIMITY) recentlyNearbyPlayers.add(uuid);
|
||||
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED
|
||||
|| getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE)
|
||||
return;
|
||||
if (voiceChannel == EnumVoiceChannelType.PROXIMITY)
|
||||
recentlyNearbyPlayers.add(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void cleanupNearbyPlayers(HashSet<EaglercraftUUID> existingPlayers) {
|
||||
nearbyPlayers.stream().filter(ud -> !existingPlayers.contains(ud)).collect(Collectors.toSet()).forEach(VoiceClientController::removeNearbyPlayer);
|
||||
nearbyPlayers.stream().filter(ud -> !existingPlayers.contains(ud)).collect(Collectors.toSet())
|
||||
.forEach(VoiceClientController::removeNearbyPlayer);
|
||||
}
|
||||
|
||||
public static final void updateVoicePosition(EaglercraftUUID uuid, double x, double y, double z) {
|
||||
|
@ -195,8 +217,10 @@ public class VoiceClientController {
|
|||
}
|
||||
|
||||
public static void setVoiceChannel(EnumVoiceChannelType channel) {
|
||||
if (voiceChannel == channel) return;
|
||||
if (channel != EnumVoiceChannelType.NONE) PlatformVoiceClient.initializeDevices();
|
||||
if (voiceChannel == channel)
|
||||
return;
|
||||
if (channel != EnumVoiceChannelType.NONE)
|
||||
PlatformVoiceClient.initializeDevices();
|
||||
PlatformVoiceClient.resetPeerStates();
|
||||
if (channel == EnumVoiceChannelType.NONE) {
|
||||
for (EaglercraftUUID uuid : nearbyPlayers) {
|
||||
|
@ -223,7 +247,7 @@ public class VoiceClientController {
|
|||
nearbyPlayers.clear();
|
||||
recentlyNearbyPlayers.clear();
|
||||
sendPacketDisconnect(null);
|
||||
} else if(voiceChannel == EnumVoiceChannelType.GLOBAL) {
|
||||
} else if (voiceChannel == EnumVoiceChannelType.GLOBAL) {
|
||||
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
|
||||
antiConcurrentModificationUUIDs.removeAll(nearbyPlayers);
|
||||
antiConcurrentModificationUUIDs.removeAll(recentlyNearbyPlayers);
|
||||
|
@ -250,12 +274,18 @@ public class VoiceClientController {
|
|||
}
|
||||
|
||||
private static boolean voicePeerErrored() {
|
||||
return PlatformVoiceClient.getPeerState() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateConnect() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateInitial() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateDesc() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateIce() == EnumVoiceChannelPeerState.FAILED;
|
||||
return PlatformVoiceClient.getPeerState() == EnumVoiceChannelPeerState.FAILED
|
||||
|| PlatformVoiceClient.getPeerStateConnect() == EnumVoiceChannelPeerState.FAILED
|
||||
|| PlatformVoiceClient.getPeerStateInitial() == EnumVoiceChannelPeerState.FAILED
|
||||
|| PlatformVoiceClient.getPeerStateDesc() == EnumVoiceChannelPeerState.FAILED
|
||||
|| PlatformVoiceClient.getPeerStateIce() == EnumVoiceChannelPeerState.FAILED;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelStatus getVoiceStatus() {
|
||||
return (!isClientSupported() || !isServerSupported()) ? EnumVoiceChannelStatus.UNAVAILABLE :
|
||||
(PlatformVoiceClient.getReadyState() != EnumVoiceChannelReadyState.DEVICE_INITIALIZED ?
|
||||
EnumVoiceChannelStatus.CONNECTING : (voicePeerErrored() ? EnumVoiceChannelStatus.UNAVAILABLE : EnumVoiceChannelStatus.CONNECTED));
|
||||
return (!isClientSupported() || !isServerSupported()) ? EnumVoiceChannelStatus.UNAVAILABLE
|
||||
: (PlatformVoiceClient.getReadyState() != EnumVoiceChannelReadyState.DEVICE_INITIALIZED
|
||||
? EnumVoiceChannelStatus.CONNECTING
|
||||
: (voicePeerErrored() ? EnumVoiceChannelStatus.UNAVAILABLE : EnumVoiceChannelStatus.CONNECTED));
|
||||
}
|
||||
|
||||
private static boolean talkStatus = false;
|
||||
|
@ -332,7 +362,7 @@ public class VoiceClientController {
|
|||
}
|
||||
|
||||
public static String getVoiceUsername(EaglercraftUUID uuid) {
|
||||
if(uuid == null) {
|
||||
if (uuid == null) {
|
||||
return "null";
|
||||
}
|
||||
String ret = uuidToNameLookup.get(uuid);
|
||||
|
@ -360,8 +390,12 @@ public class VoiceClientController {
|
|||
}
|
||||
|
||||
private static void sendPacketRequestIfNeeded(EaglercraftUUID uuid) {
|
||||
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED || getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE) return;
|
||||
if(uuid.equals(EaglerProfile.getPlayerUUID())) return;
|
||||
if (!getVoiceListening().contains(uuid)) sendPacketRequest(uuid);
|
||||
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED
|
||||
|| getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE)
|
||||
return;
|
||||
if (uuid.equals(EaglerProfile.getPlayerUUID()))
|
||||
return;
|
||||
if (!getVoiceListening().contains(uuid))
|
||||
sendPacketRequest(uuid);
|
||||
}
|
||||
}
|
|
@ -7,16 +7,24 @@ import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
|
|||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -34,13 +42,13 @@ public class VoiceSignalPackets {
|
|||
static void handleVoiceSignal(PacketBuffer streamIn) {
|
||||
try {
|
||||
int sig = streamIn.readUnsignedByte();
|
||||
switch(sig) {
|
||||
switch (sig) {
|
||||
case VOICE_SIGNAL_ALLOWED: {
|
||||
boolean voiceAvailableStat = streamIn.readUnsignedByte() == 1;
|
||||
String[] servs = null;
|
||||
if(voiceAvailableStat) {
|
||||
if (voiceAvailableStat) {
|
||||
servs = new String[streamIn.readVarIntFromBuffer()];
|
||||
for(int i = 0; i < servs.length; i++) {
|
||||
for (int i = 0; i < servs.length; i++) {
|
||||
servs[i] = streamIn.readStringFromBuffer(1024);
|
||||
}
|
||||
}
|
||||
|
@ -48,15 +56,16 @@ public class VoiceSignalPackets {
|
|||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_GLOBAL: {
|
||||
if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.GLOBAL) return;
|
||||
if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.GLOBAL)
|
||||
return;
|
||||
EaglercraftUUID[] voiceIds = new EaglercraftUUID[streamIn.readVarIntFromBuffer()];
|
||||
for(int i = 0; i < voiceIds.length; i++) {
|
||||
for (int i = 0; i < voiceIds.length; i++) {
|
||||
voiceIds[i] = streamIn.readUuid();
|
||||
}
|
||||
String[] voiceNames = null;
|
||||
if (streamIn.isReadable()) {
|
||||
voiceNames = new String[voiceIds.length];
|
||||
for(int i = 0; i < voiceNames.length; i++) {
|
||||
for (int i = 0; i < voiceNames.length; i++) {
|
||||
voiceNames[i] = streamIn.readStringFromBuffer(16);
|
||||
}
|
||||
}
|
||||
|
@ -67,21 +76,25 @@ public class VoiceSignalPackets {
|
|||
EaglercraftUUID uuid = streamIn.readUuid();
|
||||
if (streamIn.isReadable()) {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeConnect(uuid, streamIn.readBoolean());
|
||||
} else if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.PROXIMITY || VoiceClientController.getVoiceListening().contains(uuid)) {
|
||||
} else if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.PROXIMITY
|
||||
|| VoiceClientController.getVoiceListening().contains(uuid)) {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeConnectAnnounce(uuid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_DISCONNECT: {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeDisconnect(streamIn.readableBytes() > 0 ? streamIn.readUuid() : null);
|
||||
VoiceClientController.handleVoiceSignalPacketTypeDisconnect(
|
||||
streamIn.readableBytes() > 0 ? streamIn.readUuid() : null);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_ICE: {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeICECandidate(streamIn.readUuid(), streamIn.readStringFromBuffer(32767));
|
||||
VoiceClientController.handleVoiceSignalPacketTypeICECandidate(streamIn.readUuid(),
|
||||
streamIn.readStringFromBuffer(32767));
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_DESC: {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeDescription(streamIn.readUuid(), streamIn.readStringFromBuffer(32767));
|
||||
VoiceClientController.handleVoiceSignalPacketTypeDescription(streamIn.readUuid(),
|
||||
streamIn.readStringFromBuffer(32767));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -89,7 +102,7 @@ public class VoiceSignalPackets {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}catch(Throwable ex) {
|
||||
} catch (Throwable ex) {
|
||||
VoiceClientController.logger.error("Failed to handle signal packet!");
|
||||
VoiceClientController.logger.error(ex);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue