Removed common to replace it with a git submodule
This commit is contained in:
@@ -1,35 +0,0 @@
|
|||||||
# gradle
|
|
||||||
|
|
||||||
.gradle/
|
|
||||||
build/
|
|
||||||
out/
|
|
||||||
classes/
|
|
||||||
|
|
||||||
# eclipse
|
|
||||||
|
|
||||||
*.launch
|
|
||||||
|
|
||||||
# idea
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# vscode
|
|
||||||
|
|
||||||
.settings/
|
|
||||||
.vscode/
|
|
||||||
bin/
|
|
||||||
.classpath
|
|
||||||
.project
|
|
||||||
|
|
||||||
# macos
|
|
||||||
|
|
||||||
*.DS_Store
|
|
||||||
|
|
||||||
# fabric
|
|
||||||
|
|
||||||
run/
|
|
||||||
logs/
|
|
||||||
|
|
||||||
-201
@@ -1,201 +0,0 @@
|
|||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# common
|
|
||||||
The cross-version code powering Saturn Client
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id "java-library"
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
toolchain.languageVersion = JavaLanguageVersion.of(21)
|
|
||||||
}
|
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
package org.saturnclient.client;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.saturnclient.client.player.SaturnPlayer;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnClientBindings;
|
|
||||||
|
|
||||||
import dev.selimaj.session.Session;
|
|
||||||
|
|
||||||
public class ServiceClient {
|
|
||||||
private static Session session;
|
|
||||||
public static UUID uuid;
|
|
||||||
|
|
||||||
public static final List<String> availableCloaks = new ArrayList<>();
|
|
||||||
public static final List<String> availableHats = new ArrayList<>();
|
|
||||||
|
|
||||||
public static boolean connectTimeout() {
|
|
||||||
try {
|
|
||||||
session = Session.connect("wss://saturn-server.selimaj.dev", 10, TimeUnit.SECONDS);
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean authenticate() {
|
|
||||||
SaturnClientBindings.platform().onClientStopping(() -> {
|
|
||||||
if (session != null) {
|
|
||||||
try {
|
|
||||||
session.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Unable to close Saturn session", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
String accessToken = SaturnClientBindings.platform().getAccessToken();
|
|
||||||
uuid = SaturnClientBindings.platform().getUuid();
|
|
||||||
String username = SaturnClientBindings.platform().getUsername();
|
|
||||||
|
|
||||||
if (accessToken == null || uuid == null || username == null) {
|
|
||||||
SaturnClientBindings.platform().logError("No active Minecraft session found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaturnClientBindings.platform().logInfo("Authenticating with UUID: " + uuid);
|
|
||||||
|
|
||||||
if (!connectTimeout()) {
|
|
||||||
SaturnClientBindings.platform().logError("Unable to authenticate: Session Server Timeout");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceMethods.Types.Player response = session.request(ServiceMethods.Authenticate, accessToken)
|
|
||||||
.get();
|
|
||||||
|
|
||||||
for (String availableCloak : response.cloaks()) {
|
|
||||||
availableCloaks.add(availableCloak);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String availableHat : response.hats()) {
|
|
||||||
availableHats.add(availableHat);
|
|
||||||
}
|
|
||||||
|
|
||||||
eventHandlers();
|
|
||||||
|
|
||||||
SaturnPlayer.set(new SaturnPlayer(uuid, username, response.cloak(), response.hat()));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Authentication failed", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setCloak(String itemId) {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.SetCloak, itemId).whenComplete((msg, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.SendPlayer,
|
|
||||||
new ServiceMethods.Types.SendPlayerRequest(SaturnPlayer.getExternalUUIDAsString()));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Failed to set cloak (service): ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setHat(String itemId) {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.SetHat, itemId).whenComplete((msg, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.SendPlayer,
|
|
||||||
new ServiceMethods.Types.SendPlayerRequest(SaturnPlayer.getExternalUUIDAsString()));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Failed to set hat (service): ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void buyCloak(String itemId) {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.BuyCloak, itemId).whenComplete((msg, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
} else {
|
|
||||||
availableCloaks.add(itemId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Failed to buy cloak (service): ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void buyHat(String itemId) {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.BuyHat, itemId).whenComplete((msg, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
} else {
|
|
||||||
availableHats.add(itemId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Failed to buy hat (service): ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void emote(String emote) {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.Emote,
|
|
||||||
new ServiceMethods.Types.EmoteRequest(emote, SaturnPlayer.getExternalUUIDAsString()))
|
|
||||||
.whenComplete((msg, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Failed to emote (service): ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void eventHandlers() {
|
|
||||||
session.onNotification(ServiceMethods.EmoteEvent, (data) -> {
|
|
||||||
if (data == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UUID from;
|
|
||||||
try {
|
|
||||||
from = UUID.fromString(data.from());
|
|
||||||
} catch (Exception e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.emote() != null && !data.emote().isEmpty()) {
|
|
||||||
SaturnClientBindings.emotes().setEmote(from, data.emote());
|
|
||||||
} else {
|
|
||||||
SaturnClientBindings.emotes().setEmote(from, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
session.onNotification(ServiceMethods.Player, (player) -> {
|
|
||||||
System.out.println(player);
|
|
||||||
SaturnPlayer.set(player.toSaturnPlayer());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void player(UUID uuid, String name) {
|
|
||||||
try {
|
|
||||||
session.request(ServiceMethods.GetPlayer, uuid.toString())
|
|
||||||
.whenComplete((user, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
} else if (user != null) {
|
|
||||||
SaturnPlayer.set(user.toSaturnPlayer(uuid, name));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
SaturnClientBindings.platform().logError("Failed to get player", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
package org.saturnclient.client;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.saturnclient.client.ServiceMethods.Types.SendPlayerRequest;
|
|
||||||
import org.saturnclient.client.player.SaturnPlayer;
|
|
||||||
|
|
||||||
import dev.selimaj.session.types.Method;
|
|
||||||
|
|
||||||
public class ServiceMethods {
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// Types (Rust structs)
|
|
||||||
// =========================
|
|
||||||
public static class Types {
|
|
||||||
|
|
||||||
public record EmoteRequest(String emote, String[] targets) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public record EmoteEvent(String emote, String from) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public record Player(
|
|
||||||
String cloak,
|
|
||||||
String hat,
|
|
||||||
String[] cloaks,
|
|
||||||
String[] hats) {
|
|
||||||
public SaturnPlayer toSaturnPlayer(UUID uuid, String name) {
|
|
||||||
return new SaturnPlayer(uuid, name, cloak, hat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public record PlayerStream(Player player, String name, String uuid) {
|
|
||||||
public SaturnPlayer toSaturnPlayer() {
|
|
||||||
return new SaturnPlayer(UUID.fromString(uuid), name, this.player.cloak, this.player.hat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public record SendPlayerRequest(String[] targets) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// AUTH
|
|
||||||
// =========================
|
|
||||||
public static final Method<String, Types.Player, String> Authenticate = new Method<>("auth",
|
|
||||||
String.class,
|
|
||||||
Types.Player.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// EQUIP
|
|
||||||
// =========================
|
|
||||||
public static final Method<String, String, String> SetCloak = new Method<>("set_cloak",
|
|
||||||
String.class,
|
|
||||||
String.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
public static final Method<String, String, String> SetHat = new Method<>("set_hat",
|
|
||||||
String.class,
|
|
||||||
String.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// BUY
|
|
||||||
// =========================
|
|
||||||
public static final Method<String, String, String> BuyCloak = new Method<>("buy_cloak",
|
|
||||||
String.class,
|
|
||||||
String.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
public static final Method<String, String, String> BuyHat = new Method<>("buy_hat",
|
|
||||||
String.class,
|
|
||||||
String.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// EMOTE
|
|
||||||
// =========================
|
|
||||||
public static final Method<Types.EmoteRequest, Void, String> Emote = new Method<>("emote",
|
|
||||||
Types.EmoteRequest.class,
|
|
||||||
Void.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
public static final Method<Types.EmoteEvent, Void, Void> EmoteEvent = new Method<>("emote_event",
|
|
||||||
Types.EmoteEvent.class,
|
|
||||||
Void.class,
|
|
||||||
Void.class);
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// GET PLAYER
|
|
||||||
// =========================
|
|
||||||
public static final Method<String, Types.Player, String> GetPlayer = new Method<>("get_player",
|
|
||||||
String.class,
|
|
||||||
Types.Player.class,
|
|
||||||
String.class);
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// PLAYER (Server Notification)
|
|
||||||
// =========================
|
|
||||||
public static final Method<Types.PlayerStream, Void, Void> Player = new Method<>("player",
|
|
||||||
Types.PlayerStream.class,
|
|
||||||
Void.class,
|
|
||||||
Void.class);
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// SEND PLAYER
|
|
||||||
// =========================
|
|
||||||
public static final Method<SendPlayerRequest, Void, String> SendPlayer = new Method<>("send_player",
|
|
||||||
SendPlayerRequest.class,
|
|
||||||
Void.class,
|
|
||||||
String.class);
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.saturnclient.client.player;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Config;
|
|
||||||
|
|
||||||
public class Roles {
|
|
||||||
static enum Role {
|
|
||||||
OWNER,
|
|
||||||
ADMIN,
|
|
||||||
PARTNER,
|
|
||||||
CONTRIBUTOR
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<UUID, Role> ROLES = Map.of(
|
|
||||||
UUID.fromString("d362a042-28bd-49e1-a807-ae74dbe8aba9"),
|
|
||||||
Role.OWNER,
|
|
||||||
UUID.fromString("d8dc7023-179b-4460-bcf6-493fbf1289a6"),
|
|
||||||
Role.CONTRIBUTOR);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets the icon color of a specific individual, here are the different colors
|
|
||||||
*
|
|
||||||
* - Owner: Dark Red
|
|
||||||
* - Admin: Red
|
|
||||||
* - Partners: Gold
|
|
||||||
* - Contributor: Aqua
|
|
||||||
* - Other/player: White
|
|
||||||
*/
|
|
||||||
public static int getIconColor(UUID uuid) {
|
|
||||||
Role role = ROLES.get(uuid);
|
|
||||||
|
|
||||||
if (role == null) {
|
|
||||||
return 0xFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case OWNER:
|
|
||||||
return 0xAA0000;
|
|
||||||
|
|
||||||
case ADMIN:
|
|
||||||
return 0xFF5555;
|
|
||||||
|
|
||||||
case PARTNER:
|
|
||||||
return 0xFFAA00;
|
|
||||||
|
|
||||||
case CONTRIBUTOR:
|
|
||||||
return 0x55FFFF;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0xFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getSaturnIndicator() {
|
|
||||||
return Config.realisticLogo.value ? "\uE003" : "\uE002";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package org.saturnclient.client.player;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnClientBindings;
|
|
||||||
|
|
||||||
public class SaturnPlayer {
|
|
||||||
private static Map<UUID, SaturnPlayer> PLAYERS = new HashMap<>();
|
|
||||||
private static Map<String, UUID> PLAYER_NAMES = new HashMap<>();
|
|
||||||
|
|
||||||
public String cloak = "";
|
|
||||||
public String hat = "";
|
|
||||||
public final UUID uuid;
|
|
||||||
public final String name;
|
|
||||||
|
|
||||||
public SaturnPlayer(UUID uuid, String name, String cloak, String hat) {
|
|
||||||
this.cloak = cloak;
|
|
||||||
this.hat = hat;
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnPlayer get() {
|
|
||||||
UUID self = SaturnClientBindings.platform().getUuid();
|
|
||||||
if (self == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return PLAYERS.get(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnPlayer get(UUID uuid) {
|
|
||||||
return PLAYERS.get(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnPlayer get(String name) {
|
|
||||||
UUID uuid = PLAYER_NAMES.get(name);
|
|
||||||
if (uuid == null)
|
|
||||||
return null;
|
|
||||||
return PLAYERS.get(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void set(SaturnPlayer player) {
|
|
||||||
PLAYER_NAMES.put(player.name, player.uuid);
|
|
||||||
PLAYERS.put(player.uuid, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] getExternalUUIDAsString() {
|
|
||||||
UUID self = SaturnClientBindings.platform().getUuid();
|
|
||||||
return PLAYERS.keySet().stream().filter(id -> self == null || !id.equals(self)).map(UUID::toString)
|
|
||||||
.toArray(String[]::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.common.minecraft.render.IWindow;
|
|
||||||
|
|
||||||
public interface IMinecraftClient {
|
|
||||||
|
|
||||||
public File getRunDirectory();
|
|
||||||
|
|
||||||
public InputStream getResource(SaturnIdentifier identifier);
|
|
||||||
|
|
||||||
public IWindow getWindow();
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft;
|
|
||||||
|
|
||||||
public class MinecraftBinding {
|
|
||||||
public Object inner;
|
|
||||||
|
|
||||||
public MinecraftBinding(Object binding) {
|
|
||||||
this.inner = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> T get() {
|
|
||||||
try {
|
|
||||||
return (T) inner;
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.ui.SaturnScreen;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
public abstract class MinecraftProvider {
|
|
||||||
public static MinecraftProvider PROVIDER;
|
|
||||||
|
|
||||||
public static enum MinecraftScreen {
|
|
||||||
SelectWorld,
|
|
||||||
Multiplayer,
|
|
||||||
Options
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract IMinecraftClient getClient();
|
|
||||||
|
|
||||||
public abstract void setScreen(SaturnScreen screen);
|
|
||||||
|
|
||||||
public abstract void setScreen(MinecraftScreen screen);
|
|
||||||
|
|
||||||
public abstract Object createIdentifier(String namespace, String path);
|
|
||||||
|
|
||||||
public abstract boolean isKeyPressed(int key);
|
|
||||||
|
|
||||||
public abstract int getWidth(String text, int font);
|
|
||||||
|
|
||||||
public abstract void registerBufferedImageTexture(SaturnIdentifier i, BufferedImage bi);
|
|
||||||
|
|
||||||
public abstract String getKeyName(int key);
|
|
||||||
|
|
||||||
public abstract void stop();
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
public final class SaturnClientBindings {
|
|
||||||
private static SaturnPlatformBindings platform;
|
|
||||||
private static SaturnEmoteBindings emotes;
|
|
||||||
|
|
||||||
private SaturnClientBindings() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setPlatform(SaturnPlatformBindings bindings) {
|
|
||||||
platform = bindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnPlatformBindings platform() {
|
|
||||||
if (platform == null) {
|
|
||||||
throw new IllegalStateException("SaturnPlatformBindings not initialized");
|
|
||||||
}
|
|
||||||
return platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setEmotes(SaturnEmoteBindings bindings) {
|
|
||||||
emotes = bindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnEmoteBindings emotes() {
|
|
||||||
if (emotes == null) {
|
|
||||||
throw new IllegalStateException("SaturnEmoteBindings not initialized");
|
|
||||||
}
|
|
||||||
return emotes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface SaturnEmoteBindings {
|
|
||||||
void setEmote(UUID fromPlayerUuid, String emoteIdOrNull);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftBinding;
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
|
|
||||||
public class SaturnIdentifier extends MinecraftBinding {
|
|
||||||
public SaturnIdentifier(String namespace, String path) {
|
|
||||||
super(MinecraftProvider.PROVIDER.createIdentifier(namespace, path));
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnIdentifier(Object o) {
|
|
||||||
super(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnIdentifier of(String namespace, String path) {
|
|
||||||
return new SaturnIdentifier(namespace, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnIdentifier of(String fullPath) {
|
|
||||||
String[] p = fullPath.split(":", 2);
|
|
||||||
|
|
||||||
return new SaturnIdentifier(p[0], p[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnIdentifier ofVanilla(String path) {
|
|
||||||
return new SaturnIdentifier("minecraft", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.inner.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftBinding;
|
|
||||||
|
|
||||||
public class SaturnItemStack extends MinecraftBinding {
|
|
||||||
public SaturnItemStack(Object binding) {
|
|
||||||
super(binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface SaturnPlatformBindings {
|
|
||||||
String getAccessToken();
|
|
||||||
|
|
||||||
UUID getUuid();
|
|
||||||
|
|
||||||
String getUsername();
|
|
||||||
|
|
||||||
void onClientStopping(Runnable handler);
|
|
||||||
|
|
||||||
void logInfo(String message);
|
|
||||||
|
|
||||||
void logError(String message);
|
|
||||||
|
|
||||||
void logError(String message, Throwable throwable);
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftBinding;
|
|
||||||
|
|
||||||
public class SaturnQuaternionf extends MinecraftBinding {
|
|
||||||
public SaturnQuaternionf(Object o) {
|
|
||||||
super(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.bindings;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftBinding;
|
|
||||||
|
|
||||||
public class SaturnSprite extends MinecraftBinding {
|
|
||||||
public SaturnSprite(Object binding) {
|
|
||||||
super(binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.render;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnQuaternionf;
|
|
||||||
|
|
||||||
public interface IMatrixStack {
|
|
||||||
public void translate(double x, double y, double z);
|
|
||||||
|
|
||||||
public void translate(float x, float y, float z);
|
|
||||||
|
|
||||||
public void scale(float x, float y, float z);
|
|
||||||
|
|
||||||
public void multiply(SaturnQuaternionf quaternion);
|
|
||||||
|
|
||||||
public void multiply(SaturnQuaternionf quaternion, float originX, float originY, float originZ);
|
|
||||||
|
|
||||||
public void push();
|
|
||||||
|
|
||||||
public void pop();
|
|
||||||
|
|
||||||
public Object peek();
|
|
||||||
|
|
||||||
public boolean isEmpty();
|
|
||||||
|
|
||||||
public void loadIdentity();
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.saturnclient.common.minecraft.render;
|
|
||||||
|
|
||||||
public interface IWindow {
|
|
||||||
public int getWidth();
|
|
||||||
|
|
||||||
public int getHeight();
|
|
||||||
|
|
||||||
public int getFramebufferWidth();
|
|
||||||
|
|
||||||
public int getFramebufferHeight();
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package org.saturnclient.config;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.ConfigManager;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class AnimationConfig {
|
|
||||||
public static ConfigManager config;
|
|
||||||
|
|
||||||
// Logo
|
|
||||||
public static final AnimationConfig logo = new AnimationConfig(true, 700, 0);
|
|
||||||
|
|
||||||
// Main menu
|
|
||||||
public static final AnimationConfig mainMenu = new AnimationConfig(true, 700, 120);
|
|
||||||
|
|
||||||
// Mod menu
|
|
||||||
public static final AnimationConfig modMenu = new AnimationConfig(true, 700, 20);
|
|
||||||
|
|
||||||
// Shift menu
|
|
||||||
public static final AnimationConfig shiftMenu = new AnimationConfig(true, 700, 100);
|
|
||||||
|
|
||||||
// Cosmetics menu
|
|
||||||
public static final AnimationConfig cosmeticsMenu = new AnimationConfig(true, 700, 40);
|
|
||||||
|
|
||||||
// Emote wheel
|
|
||||||
public static final AnimationConfig emoteWheel = new AnimationConfig(true, 700, 40);
|
|
||||||
|
|
||||||
public static void init(ConfigManager parent) {
|
|
||||||
config = new ConfigManager(parent, "Animations");
|
|
||||||
|
|
||||||
logo.init("Logo");
|
|
||||||
mainMenu.init("Main Menu");
|
|
||||||
modMenu.init("Mod Menu");
|
|
||||||
shiftMenu.init("Shift Menu");
|
|
||||||
cosmeticsMenu.init("Cosmetics Menu");
|
|
||||||
emoteWheel.init("Emote Wheel");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animation properties
|
|
||||||
public final Property<Integer> duration;
|
|
||||||
public final Property<Integer> stagger;
|
|
||||||
public final Property<Integer> curve;
|
|
||||||
|
|
||||||
public AnimationConfig(boolean enabled, int delay, int stagger) {
|
|
||||||
this.duration = Property.integer(delay);
|
|
||||||
this.stagger = Property.integer(stagger);
|
|
||||||
this.curve = Property.select(1, "Ease In Out Cubic", "Ease Out Cubic", "Ease In Out Back");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(String name) {
|
|
||||||
// config.property("Enable " + name + " Animations", this.enabled);
|
|
||||||
config.property(name + " Duration", this.duration);
|
|
||||||
config.property(name + " Stagger", this.stagger);
|
|
||||||
config.property(name + " Curve", this.curve);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package org.saturnclient.config;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.manager.ConfigManager;
|
|
||||||
import org.saturnclient.config.manager.Key;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.resources.Textures;
|
|
||||||
|
|
||||||
public class Config {
|
|
||||||
public static ConfigManager config;
|
|
||||||
|
|
||||||
public static Property<Boolean> realisticLogo = Property.bool(false);
|
|
||||||
public static Property<Boolean> saturnTitleScreen = Property.bool(true);
|
|
||||||
public static Property<Boolean> cloakPhysics = Property.bool(true);
|
|
||||||
public static Property<Integer> openEmoteWheel = Property.keybinding(Key.GLFW_KEY_B);
|
|
||||||
public static Property<Boolean> stagger = Property.bool(true);
|
|
||||||
|
|
||||||
public static SaturnIdentifier getLogo() {
|
|
||||||
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
File configFile = new File(MinecraftProvider.PROVIDER.getClient().getRunDirectory(), "saturn.json");
|
|
||||||
config = new ConfigManager(configFile, "Saturn Client");
|
|
||||||
|
|
||||||
config.property("Realistic logo", realisticLogo);
|
|
||||||
config.property("Saturn client title screen", saturnTitleScreen);
|
|
||||||
config.property("Open Emote Wheel", openEmoteWheel);
|
|
||||||
config.property("Cloak Physics", cloakPhysics);
|
|
||||||
config.property("Stagger Animations", stagger);
|
|
||||||
|
|
||||||
// Initialize a sub namespace for theme
|
|
||||||
Theme.init(config);
|
|
||||||
|
|
||||||
// Initialize a sub namespace for animations
|
|
||||||
AnimationConfig.init(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package org.saturnclient.config;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.ConfigManager;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class Theme {
|
|
||||||
// Main UI background (slightly warm dark to match Saturn tone)
|
|
||||||
public static final Property<Integer> BACKGROUND = Property.color(0xFF12100D);
|
|
||||||
|
|
||||||
// Default text color
|
|
||||||
public static final Property<Integer> FOREGROUND = Property.color(0xFFF2E6D2);
|
|
||||||
|
|
||||||
// Widget default background (normal state)
|
|
||||||
public static final Property<Integer> PRIMARY = Property.color(0xFF1C1915);
|
|
||||||
|
|
||||||
// Widget text color
|
|
||||||
public static final Property<Integer> PRIMARY_FG = Property.color(0xFFEAD9B8);
|
|
||||||
|
|
||||||
// Saturn brand color (hovered / enabled / selected)
|
|
||||||
public static final Property<Integer> ACCENT = Property.color(0xFFE2BF7D);
|
|
||||||
|
|
||||||
// Text/icons shown on accent background
|
|
||||||
public static final Property<Integer> ACCENT_FG = Property.color(0xFF1A140A);
|
|
||||||
|
|
||||||
// Misc colors
|
|
||||||
public static final Property<Integer> SCROLL = Property.color(0xFFE2BF7D);
|
|
||||||
|
|
||||||
// UI metrics
|
|
||||||
public static final Property<Integer> BG_RADIUS = Property.integer(12);
|
|
||||||
public static final Property<Integer> WIDGET_RADIUS = Property.integer(10);
|
|
||||||
|
|
||||||
// Font
|
|
||||||
public static final Property<Integer> FONT = Property.font(2);
|
|
||||||
|
|
||||||
public static void init(ConfigManager parent) {
|
|
||||||
ConfigManager config = new ConfigManager(parent, "UI Style");
|
|
||||||
config.property("Background", BACKGROUND);
|
|
||||||
config.property("Foreground", FOREGROUND);
|
|
||||||
config.property("Primary", PRIMARY);
|
|
||||||
config.property("Primary Foreground", PRIMARY_FG);
|
|
||||||
config.property("Accent", ACCENT);
|
|
||||||
config.property("Accent Foreground", ACCENT_FG);
|
|
||||||
config.property("Scrollbar Color", SCROLL);
|
|
||||||
|
|
||||||
config.property("Background Radius", BG_RADIUS);
|
|
||||||
config.property("Widget Radius", WIDGET_RADIUS);
|
|
||||||
|
|
||||||
config.property("Font", FONT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* primary by default, accent if true
|
|
||||||
*/
|
|
||||||
public static int getBg(boolean hover) {
|
|
||||||
return hover ? ACCENT.value : PRIMARY.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Foreground) primary by default, accent if true
|
|
||||||
*/
|
|
||||||
public static int getFg(boolean hover) {
|
|
||||||
return hover ? ACCENT_FG.value : PRIMARY_FG.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multiplies existing alpha with 0–255 alpha.
|
|
||||||
*/
|
|
||||||
public static int withAlpha(int alpha, int color) {
|
|
||||||
alpha = Math.max(0, Math.min(255, alpha));
|
|
||||||
|
|
||||||
int originalAlpha = (color >>> 24) & 0xFF;
|
|
||||||
|
|
||||||
// Merge (multiply) alphas
|
|
||||||
int merged = (originalAlpha * alpha) / 255;
|
|
||||||
|
|
||||||
return (color & 0x00FFFFFF) | (merged << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multiplies existing alpha with 0.0–1.0 alpha.
|
|
||||||
*/
|
|
||||||
public static int withAlpha(float alpha, int color) {
|
|
||||||
alpha = Math.max(0f, Math.min(1f, alpha));
|
|
||||||
|
|
||||||
int originalAlpha = (color >>> 24) & 0xFF;
|
|
||||||
|
|
||||||
int merged = (int) (originalAlpha * alpha);
|
|
||||||
|
|
||||||
return (color & 0x00FFFFFF) | (merged << 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
package org.saturnclient.config.manager;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ConfigManager {
|
|
||||||
|
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
||||||
private static File configFile;
|
|
||||||
|
|
||||||
// SINGLE ROOT TREE
|
|
||||||
private static final Map<String, Property<?>> ROOT = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
private static JsonNode cachedJson = null;
|
|
||||||
|
|
||||||
private final Map<String, Property<?>> currentMap;
|
|
||||||
|
|
||||||
private final String[] path;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a root namespace
|
|
||||||
*/
|
|
||||||
public ConfigManager(File configFile, String namespace) {
|
|
||||||
ConfigManager.configFile = configFile;
|
|
||||||
this.currentMap = new LinkedHashMap<>();
|
|
||||||
this.path = new String[] { namespace };
|
|
||||||
|
|
||||||
ROOT.put(namespace, Property.namespace(currentMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a root namespace
|
|
||||||
*/
|
|
||||||
public ConfigManager(String namespace) {
|
|
||||||
this.currentMap = new LinkedHashMap<>();
|
|
||||||
this.path = new String[] { namespace };
|
|
||||||
|
|
||||||
ROOT.put(namespace, Property.namespace(currentMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a sub-namespace inside a parent
|
|
||||||
*/
|
|
||||||
public ConfigManager(ConfigManager parent, String namespace) {
|
|
||||||
this.currentMap = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
this.path = new String[parent.path.length + 1];
|
|
||||||
System.arraycopy(parent.path, 0, this.path, 0, parent.path.length);
|
|
||||||
this.path[this.path.length - 1] = namespace;
|
|
||||||
|
|
||||||
parent.property(namespace, Property.namespace(currentMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a property
|
|
||||||
*/
|
|
||||||
public <T> Property<T> property(String name, Property<T> value) {
|
|
||||||
currentMap.put(name, value);
|
|
||||||
loadSingleProperty(name, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add empty namespace
|
|
||||||
*/
|
|
||||||
public ConfigManager sub(String name) {
|
|
||||||
return new ConfigManager(this, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load entire config
|
|
||||||
*/
|
|
||||||
public void load() {
|
|
||||||
JsonNode json = loadAndCache();
|
|
||||||
if (json == null || !json.isObject())
|
|
||||||
return;
|
|
||||||
|
|
||||||
loadRecursive((ObjectNode) json, ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save entire config
|
|
||||||
*/
|
|
||||||
public static void save() {
|
|
||||||
|
|
||||||
ObjectNode rootJson = MAPPER.createObjectNode();
|
|
||||||
saveRecursive(rootJson, ROOT);
|
|
||||||
|
|
||||||
try {
|
|
||||||
MAPPER.writerWithDefaultPrettyPrinter().writeValue(configFile, rootJson);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive save
|
|
||||||
*/
|
|
||||||
private static void saveRecursive(ObjectNode json, Map<String, Property<?>> map) {
|
|
||||||
map.forEach((name, prop) -> {
|
|
||||||
if (prop.isNamespace()) {
|
|
||||||
|
|
||||||
ObjectNode child = json.objectNode();
|
|
||||||
saveRecursive(child, prop.getNamespaceMap());
|
|
||||||
|
|
||||||
json.set(name, child);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
json.set(name, prop.toJson());
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive load
|
|
||||||
*/
|
|
||||||
private static void loadRecursive(ObjectNode json, Map<String, Property<?>> map) {
|
|
||||||
|
|
||||||
map.forEach((name, prop) -> {
|
|
||||||
|
|
||||||
JsonNode element = json.get(name);
|
|
||||||
if (element == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (prop.isNamespace() && element.isObject()) {
|
|
||||||
|
|
||||||
loadRecursive((ObjectNode) element, prop.getNamespaceMap());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
prop.loadFromJson(element);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load only a single property immediately after creation
|
|
||||||
*/
|
|
||||||
private void loadSingleProperty(String name, Property<?> prop) {
|
|
||||||
|
|
||||||
JsonNode source = cachedJson != null ? cachedJson : loadAndCache();
|
|
||||||
if (source == null || !source.isObject())
|
|
||||||
return;
|
|
||||||
|
|
||||||
JsonNode currentScope = source;
|
|
||||||
|
|
||||||
for (String segment : path) {
|
|
||||||
|
|
||||||
JsonNode next = currentScope.get(segment);
|
|
||||||
|
|
||||||
if (next != null && next.isObject()) {
|
|
||||||
currentScope = next;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonNode element = currentScope.get(name);
|
|
||||||
|
|
||||||
if (element != null) {
|
|
||||||
prop.loadFromJson(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads file and caches json
|
|
||||||
*/
|
|
||||||
private JsonNode loadAndCache() {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
|
|
||||||
Files.writeString(configFile.toPath(), "{}");
|
|
||||||
cachedJson = MAPPER.createObjectNode();
|
|
||||||
return cachedJson;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cachedJson = MAPPER.readTree(configFile);
|
|
||||||
return cachedJson;
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Property<?>> getProperties() {
|
|
||||||
return currentMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
package org.saturnclient.config.manager;
|
|
||||||
|
|
||||||
public class Key {
|
|
||||||
/** Printable keys. */
|
|
||||||
public static final int GLFW_KEY_SPACE = 32,
|
|
||||||
GLFW_KEY_APOSTROPHE = 39,
|
|
||||||
GLFW_KEY_COMMA = 44,
|
|
||||||
GLFW_KEY_MINUS = 45,
|
|
||||||
GLFW_KEY_PERIOD = 46,
|
|
||||||
GLFW_KEY_SLASH = 47,
|
|
||||||
GLFW_KEY_0 = 48,
|
|
||||||
GLFW_KEY_1 = 49,
|
|
||||||
GLFW_KEY_2 = 50,
|
|
||||||
GLFW_KEY_3 = 51,
|
|
||||||
GLFW_KEY_4 = 52,
|
|
||||||
GLFW_KEY_5 = 53,
|
|
||||||
GLFW_KEY_6 = 54,
|
|
||||||
GLFW_KEY_7 = 55,
|
|
||||||
GLFW_KEY_8 = 56,
|
|
||||||
GLFW_KEY_9 = 57,
|
|
||||||
GLFW_KEY_SEMICOLON = 59,
|
|
||||||
GLFW_KEY_EQUAL = 61,
|
|
||||||
GLFW_KEY_A = 65,
|
|
||||||
GLFW_KEY_B = 66,
|
|
||||||
GLFW_KEY_C = 67,
|
|
||||||
GLFW_KEY_D = 68,
|
|
||||||
GLFW_KEY_E = 69,
|
|
||||||
GLFW_KEY_F = 70,
|
|
||||||
GLFW_KEY_G = 71,
|
|
||||||
GLFW_KEY_H = 72,
|
|
||||||
GLFW_KEY_I = 73,
|
|
||||||
GLFW_KEY_J = 74,
|
|
||||||
GLFW_KEY_K = 75,
|
|
||||||
GLFW_KEY_L = 76,
|
|
||||||
GLFW_KEY_M = 77,
|
|
||||||
GLFW_KEY_N = 78,
|
|
||||||
GLFW_KEY_O = 79,
|
|
||||||
GLFW_KEY_P = 80,
|
|
||||||
GLFW_KEY_Q = 81,
|
|
||||||
GLFW_KEY_R = 82,
|
|
||||||
GLFW_KEY_S = 83,
|
|
||||||
GLFW_KEY_T = 84,
|
|
||||||
GLFW_KEY_U = 85,
|
|
||||||
GLFW_KEY_V = 86,
|
|
||||||
GLFW_KEY_W = 87,
|
|
||||||
GLFW_KEY_X = 88,
|
|
||||||
GLFW_KEY_Y = 89,
|
|
||||||
GLFW_KEY_Z = 90,
|
|
||||||
GLFW_KEY_LEFT_BRACKET = 91,
|
|
||||||
GLFW_KEY_BACKSLASH = 92,
|
|
||||||
GLFW_KEY_RIGHT_BRACKET = 93,
|
|
||||||
GLFW_KEY_GRAVE_ACCENT = 96,
|
|
||||||
GLFW_KEY_WORLD_1 = 161,
|
|
||||||
GLFW_KEY_WORLD_2 = 162;
|
|
||||||
|
|
||||||
/** Function keys. */
|
|
||||||
public static final int GLFW_KEY_ESCAPE = 256,
|
|
||||||
GLFW_KEY_ENTER = 257,
|
|
||||||
GLFW_KEY_TAB = 258,
|
|
||||||
GLFW_KEY_BACKSPACE = 259,
|
|
||||||
GLFW_KEY_INSERT = 260,
|
|
||||||
GLFW_KEY_DELETE = 261,
|
|
||||||
GLFW_KEY_RIGHT = 262,
|
|
||||||
GLFW_KEY_LEFT = 263,
|
|
||||||
GLFW_KEY_DOWN = 264,
|
|
||||||
GLFW_KEY_UP = 265,
|
|
||||||
GLFW_KEY_PAGE_UP = 266,
|
|
||||||
GLFW_KEY_PAGE_DOWN = 267,
|
|
||||||
GLFW_KEY_HOME = 268,
|
|
||||||
GLFW_KEY_END = 269,
|
|
||||||
GLFW_KEY_CAPS_LOCK = 280,
|
|
||||||
GLFW_KEY_SCROLL_LOCK = 281,
|
|
||||||
GLFW_KEY_NUM_LOCK = 282,
|
|
||||||
GLFW_KEY_PRINT_SCREEN = 283,
|
|
||||||
GLFW_KEY_PAUSE = 284,
|
|
||||||
GLFW_KEY_F1 = 290,
|
|
||||||
GLFW_KEY_F2 = 291,
|
|
||||||
GLFW_KEY_F3 = 292,
|
|
||||||
GLFW_KEY_F4 = 293,
|
|
||||||
GLFW_KEY_F5 = 294,
|
|
||||||
GLFW_KEY_F6 = 295,
|
|
||||||
GLFW_KEY_F7 = 296,
|
|
||||||
GLFW_KEY_F8 = 297,
|
|
||||||
GLFW_KEY_F9 = 298,
|
|
||||||
GLFW_KEY_F10 = 299,
|
|
||||||
GLFW_KEY_F11 = 300,
|
|
||||||
GLFW_KEY_F12 = 301,
|
|
||||||
GLFW_KEY_F13 = 302,
|
|
||||||
GLFW_KEY_F14 = 303,
|
|
||||||
GLFW_KEY_F15 = 304,
|
|
||||||
GLFW_KEY_F16 = 305,
|
|
||||||
GLFW_KEY_F17 = 306,
|
|
||||||
GLFW_KEY_F18 = 307,
|
|
||||||
GLFW_KEY_F19 = 308,
|
|
||||||
GLFW_KEY_F20 = 309,
|
|
||||||
GLFW_KEY_F21 = 310,
|
|
||||||
GLFW_KEY_F22 = 311,
|
|
||||||
GLFW_KEY_F23 = 312,
|
|
||||||
GLFW_KEY_F24 = 313,
|
|
||||||
GLFW_KEY_F25 = 314,
|
|
||||||
GLFW_KEY_KP_0 = 320,
|
|
||||||
GLFW_KEY_KP_1 = 321,
|
|
||||||
GLFW_KEY_KP_2 = 322,
|
|
||||||
GLFW_KEY_KP_3 = 323,
|
|
||||||
GLFW_KEY_KP_4 = 324,
|
|
||||||
GLFW_KEY_KP_5 = 325,
|
|
||||||
GLFW_KEY_KP_6 = 326,
|
|
||||||
GLFW_KEY_KP_7 = 327,
|
|
||||||
GLFW_KEY_KP_8 = 328,
|
|
||||||
GLFW_KEY_KP_9 = 329,
|
|
||||||
GLFW_KEY_KP_DECIMAL = 330,
|
|
||||||
GLFW_KEY_KP_DIVIDE = 331,
|
|
||||||
GLFW_KEY_KP_MULTIPLY = 332,
|
|
||||||
GLFW_KEY_KP_SUBTRACT = 333,
|
|
||||||
GLFW_KEY_KP_ADD = 334,
|
|
||||||
GLFW_KEY_KP_ENTER = 335,
|
|
||||||
GLFW_KEY_KP_EQUAL = 336,
|
|
||||||
GLFW_KEY_LEFT_SHIFT = 340,
|
|
||||||
GLFW_KEY_LEFT_CONTROL = 341,
|
|
||||||
GLFW_KEY_LEFT_ALT = 342,
|
|
||||||
GLFW_KEY_LEFT_SUPER = 343,
|
|
||||||
GLFW_KEY_RIGHT_SHIFT = 344,
|
|
||||||
GLFW_KEY_RIGHT_CONTROL = 345,
|
|
||||||
GLFW_KEY_RIGHT_ALT = 346,
|
|
||||||
GLFW_KEY_RIGHT_SUPER = 347,
|
|
||||||
GLFW_KEY_MENU = 348,
|
|
||||||
GLFW_KEY_LAST = GLFW_KEY_MENU;
|
|
||||||
|
|
||||||
/** If this bit is set one or more Shift keys were held down. */
|
|
||||||
public static final int GLFW_MOD_SHIFT = 0x1;
|
|
||||||
|
|
||||||
/** If this bit is set one or more Control keys were held down. */
|
|
||||||
public static final int GLFW_MOD_CONTROL = 0x2;
|
|
||||||
|
|
||||||
/** If this bit is set one or more Alt keys were held down. */
|
|
||||||
public static final int GLFW_MOD_ALT = 0x4;
|
|
||||||
|
|
||||||
/** If this bit is set one or more Super keys were held down. */
|
|
||||||
public static final int GLFW_MOD_SUPER = 0x8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this bit is set the Caps Lock key is enabled and the
|
|
||||||
* {@link #GLFW_LOCK_KEY_MODS LOCK_KEY_MODS} input mode is set.
|
|
||||||
*/
|
|
||||||
public static final int GLFW_MOD_CAPS_LOCK = 0x10;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this bit is set the Num Lock key is enabled and the
|
|
||||||
* {@link #GLFW_LOCK_KEY_MODS LOCK_KEY_MODS} input mode is set.
|
|
||||||
*/
|
|
||||||
public static final int GLFW_MOD_NUM_LOCK = 0x20;
|
|
||||||
}
|
|
||||||
@@ -1,320 +0,0 @@
|
|||||||
package org.saturnclient.config.manager;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Property<T> {
|
|
||||||
|
|
||||||
public static class NamedProperty<T> {
|
|
||||||
public String name;
|
|
||||||
public Property<T> prop;
|
|
||||||
|
|
||||||
public NamedProperty(String name, Property<T> value) {
|
|
||||||
this.name = name;
|
|
||||||
this.prop = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum PropertyType {
|
|
||||||
BOOLEAN,
|
|
||||||
INTEGER,
|
|
||||||
FLOAT,
|
|
||||||
STRING,
|
|
||||||
HEX,
|
|
||||||
NAMESPACE,
|
|
||||||
SELECT,
|
|
||||||
KEYBINDING,
|
|
||||||
}
|
|
||||||
|
|
||||||
public T value;
|
|
||||||
public boolean isReset = false;
|
|
||||||
private T defaultValue;
|
|
||||||
private String[] availableValues;
|
|
||||||
private final PropertyType type;
|
|
||||||
private boolean wasPressedLastTick = false;
|
|
||||||
|
|
||||||
private Property(T value, PropertyType type) {
|
|
||||||
this.value = value;
|
|
||||||
this.defaultValue = value;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Factory Methods ----------
|
|
||||||
|
|
||||||
public static <T> Property<T> from(T value) {
|
|
||||||
if (value instanceof Boolean)
|
|
||||||
return new Property<>(value, PropertyType.BOOLEAN);
|
|
||||||
if (value instanceof Integer)
|
|
||||||
return new Property<>(value, PropertyType.INTEGER);
|
|
||||||
if (value instanceof Float)
|
|
||||||
return new Property<>(value, PropertyType.FLOAT);
|
|
||||||
if (value instanceof String)
|
|
||||||
return new Property<>(value, PropertyType.STRING);
|
|
||||||
if (valueIsNamespace(value))
|
|
||||||
return new Property<>(value, PropertyType.NAMESPACE);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Integer> font(int value) {
|
|
||||||
return select(value, "Default", "Inter", "Inter bold");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Integer> select(Integer value, String... availableValues) {
|
|
||||||
Property<Integer> property = new Property<>(value, PropertyType.SELECT);
|
|
||||||
property.availableValues = availableValues;
|
|
||||||
return property;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Map<String, Property<?>>> namespace(Map<String, Property<?>> value) {
|
|
||||||
return new Property<>(value, PropertyType.NAMESPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Boolean> bool(boolean value) {
|
|
||||||
return new Property<>(value, PropertyType.BOOLEAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Integer> integer(int value) {
|
|
||||||
return new Property<>(value, PropertyType.INTEGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Float> floatProp(float value) {
|
|
||||||
return new Property<>(value, PropertyType.FLOAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<String> string(String value) {
|
|
||||||
return new Property<>(value, PropertyType.STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Integer> color(int value) {
|
|
||||||
return new Property<>(value, PropertyType.HEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Property<Integer> keybinding(int value) {
|
|
||||||
return new Property<>(value, PropertyType.KEYBINDING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Select Helpers ----------
|
|
||||||
|
|
||||||
public void next() {
|
|
||||||
if (type == PropertyType.SELECT) {
|
|
||||||
int i = (Integer) value;
|
|
||||||
setValue((i < availableValues.length - 1) ? i + 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void prev() {
|
|
||||||
if (type == PropertyType.SELECT) {
|
|
||||||
int i = (Integer) value;
|
|
||||||
setValue((i > 0) ? i - 1 : availableValues.length - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelection(int selection) {
|
|
||||||
if (type == PropertyType.SELECT && selection >= 0 && selection < availableValues.length) {
|
|
||||||
setValue(selection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSelection() {
|
|
||||||
return (type == PropertyType.SELECT) ? availableValues[(Integer) value] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Lifecycle ----------
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
value = defaultValue;
|
|
||||||
isReset = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Map<String, Property<?>> getNamespaceValue() {
|
|
||||||
if (type == PropertyType.NAMESPACE && value instanceof Map) {
|
|
||||||
return (Map<String, Property<?>>) value;
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Property is not a namespace");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- JSON Serialization ----------
|
|
||||||
|
|
||||||
public JsonNode toJson() {
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
|
|
||||||
case BOOLEAN:
|
|
||||||
return JsonNodeFactory.instance.booleanNode((Boolean) value);
|
|
||||||
|
|
||||||
case INTEGER:
|
|
||||||
return JsonNodeFactory.instance.numberNode((Integer) value);
|
|
||||||
|
|
||||||
case FLOAT:
|
|
||||||
return JsonNodeFactory.instance.numberNode((Float) value);
|
|
||||||
|
|
||||||
case STRING:
|
|
||||||
return JsonNodeFactory.instance.textNode((String) value);
|
|
||||||
|
|
||||||
case HEX:
|
|
||||||
return JsonNodeFactory.instance.textNode(
|
|
||||||
String.format("#%08X", (Integer) value));
|
|
||||||
|
|
||||||
case KEYBINDING:
|
|
||||||
case SELECT:
|
|
||||||
return JsonNodeFactory.instance.numberNode((Integer) value);
|
|
||||||
|
|
||||||
case NAMESPACE:
|
|
||||||
|
|
||||||
ObjectNode nested = JsonNodeFactory.instance.objectNode();
|
|
||||||
|
|
||||||
getNamespaceValue().forEach((k, v) -> {
|
|
||||||
nested.set(k, v.toJson());
|
|
||||||
});
|
|
||||||
|
|
||||||
return nested;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return JsonNodeFactory.instance.textNode(String.valueOf(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadFromJson(JsonNode element) {
|
|
||||||
|
|
||||||
if (element == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
|
|
||||||
case BOOLEAN:
|
|
||||||
if (element.isBoolean())
|
|
||||||
setValue(element.booleanValue());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INTEGER:
|
|
||||||
if (element.isInt())
|
|
||||||
setValue(element.intValue());
|
|
||||||
else if (element.isTextual())
|
|
||||||
setValue(parseHexToInt(element.textValue()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FLOAT:
|
|
||||||
if (element.isNumber())
|
|
||||||
setValue(element.floatValue());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STRING:
|
|
||||||
if (element.isTextual())
|
|
||||||
setValue(element.textValue());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HEX:
|
|
||||||
if (element.isTextual())
|
|
||||||
setValue(parseHexToInt(element.textValue()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NAMESPACE:
|
|
||||||
|
|
||||||
if (element.isObject()) {
|
|
||||||
|
|
||||||
ObjectNode obj = (ObjectNode) element;
|
|
||||||
|
|
||||||
getNamespaceValue().forEach((k, v) -> {
|
|
||||||
v.loadFromJson(obj.get(k));
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SELECT:
|
|
||||||
if (element.isInt())
|
|
||||||
setSelection(element.intValue());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYBINDING:
|
|
||||||
if (element.isInt())
|
|
||||||
setValue(element.intValue());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Utility ----------
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean valueIsNamespace(Object obj) {
|
|
||||||
return obj instanceof Map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void setValue(Object value) {
|
|
||||||
this.value = (T) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void setValue(Object value, Object defaultValue) {
|
|
||||||
this.value = (T) value;
|
|
||||||
this.defaultValue = (T) defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NamedProperty<T> named(String name) {
|
|
||||||
return new NamedProperty<>(name, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Keybindings (no SaturnClient) ----------
|
|
||||||
|
|
||||||
public boolean isKeyPressed() {
|
|
||||||
|
|
||||||
return (Integer) value != -1 &&
|
|
||||||
MinecraftProvider.PROVIDER.isKeyPressed((Integer) value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean wasKeyPressed() {
|
|
||||||
boolean pressed = isKeyPressed();
|
|
||||||
|
|
||||||
boolean result = pressed && !wasPressedLastTick;
|
|
||||||
|
|
||||||
wasPressedLastTick = pressed;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- HEX ----------
|
|
||||||
|
|
||||||
public static int parseHexToInt(String hex) {
|
|
||||||
|
|
||||||
hex = hex.replace("#", "");
|
|
||||||
|
|
||||||
if (hex.length() == 6)
|
|
||||||
hex = "FF" + hex;
|
|
||||||
|
|
||||||
if (hex.length() != 8)
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Hex must be 6 or 8 chars long, got '" + hex + "'");
|
|
||||||
|
|
||||||
return (int) Long.parseLong(hex, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Misc ----------
|
|
||||||
|
|
||||||
public Property<T> copy() {
|
|
||||||
return new Property<>(this.value, this.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNamespace() {
|
|
||||||
return type == PropertyType.NAMESPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Map<String, Property<?>> getNamespaceMap() {
|
|
||||||
return isNamespace() ? (Map<String, Property<?>>) value : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package org.saturnclient.cosmetics;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Emotes {
|
|
||||||
public static List<String> availableEmotes = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void initialize() {
|
|
||||||
availableEmotes.add("tpose");
|
|
||||||
availableEmotes.add("back_flip");
|
|
||||||
availableEmotes.add("facepalm");
|
|
||||||
availableEmotes.add("cry");
|
|
||||||
availableEmotes.add("giga_chad");
|
|
||||||
availableEmotes.add("front_flip");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.saturnclient.cosmetics;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.saturnclient.client.ServiceClient;
|
|
||||||
import org.saturnclient.client.player.SaturnPlayer;
|
|
||||||
|
|
||||||
public class Hats {
|
|
||||||
public static final String[] ALL_HATS = { "horns_black", "horns_white", "halo", "halo_black" };
|
|
||||||
public static List<String> availableHats = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void initialize() {
|
|
||||||
availableHats.add(0, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setHat(String hatName) {
|
|
||||||
if (availableHats.contains(hatName)) {
|
|
||||||
setHat(ServiceClient.uuid, hatName);
|
|
||||||
ServiceClient.setHat(hatName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setHat(UUID uuid, String hatName) {
|
|
||||||
SaturnPlayer player = SaturnPlayer.get(uuid);
|
|
||||||
if (player != null) {
|
|
||||||
player.hat = hatName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.saturnclient.modules;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public interface HudMod {
|
|
||||||
public ModDimensions getDimensions();
|
|
||||||
|
|
||||||
public void renderDummy(RenderScope scope);
|
|
||||||
|
|
||||||
public void renderHud(RenderScope scope);
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package org.saturnclient.modules;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.config.manager.Property.NamedProperty;
|
|
||||||
|
|
||||||
public class ModDimensions {
|
|
||||||
public Property<Integer> x = Property.integer(0);
|
|
||||||
public Property<Integer> y = Property.integer(0);
|
|
||||||
public Property<Float> scale = Property.floatProp(1.0f);
|
|
||||||
public Property<Integer> bgColor = Property.color(0x00000000);
|
|
||||||
public Property<Integer> fgColor = Property.color(0xFFffffff);
|
|
||||||
public Property<Integer> radius = Property.integer(0);
|
|
||||||
public Property<Integer> font = Property.font(0);
|
|
||||||
public boolean renderBackground = true;
|
|
||||||
|
|
||||||
public int width = 0;
|
|
||||||
public int height = 0;
|
|
||||||
|
|
||||||
public NamedProperty<Map<String, Property<?>>> prop() {
|
|
||||||
return Property.namespace(Map.of(
|
|
||||||
"X", x,
|
|
||||||
"Y", y,
|
|
||||||
"Scale", scale,
|
|
||||||
"Background Color", bgColor,
|
|
||||||
"Foreground Color", fgColor,
|
|
||||||
"Corner Radius", radius,
|
|
||||||
"Font", font)).named("In-Game Display");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModDimensions() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModDimensions(int width, int height) {
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModDimensions(int x, int y, int width, int height) {
|
|
||||||
this.x.value = x;
|
|
||||||
this.y.value = y;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModDimensions(int x, int y, int width, int height, float scale) {
|
|
||||||
this.x.value = x;
|
|
||||||
this.y.value = y;
|
|
||||||
this.scale.value = scale;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.saturnclient.modules;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ModManager {
|
|
||||||
public static List<Module> ENABLED_MODS = new ArrayList<>();
|
|
||||||
public static Module[] MODS = {};
|
|
||||||
|
|
||||||
public static void init(ModuleProvider provider) {
|
|
||||||
MODS = provider.getMods();
|
|
||||||
updateEnabledModules();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized void updateEnabledModules() {
|
|
||||||
ENABLED_MODS.clear();
|
|
||||||
for (Module m : MODS) {
|
|
||||||
if (m.isEnabled()) {
|
|
||||||
ENABLED_MODS.add(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Module[] getAllMods() {
|
|
||||||
return MODS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ModuleProvider {
|
|
||||||
Module[] getMods();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.saturnclient.modules;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.manager.ConfigManager;
|
|
||||||
import org.saturnclient.config.manager.Property.NamedProperty;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Textures;
|
|
||||||
|
|
||||||
public abstract class Module {
|
|
||||||
private final ModuleDetails details;
|
|
||||||
private final ConfigManager configManager;
|
|
||||||
|
|
||||||
public Module(ModuleDetails details, NamedProperty<?>... props) {
|
|
||||||
this.details = details;
|
|
||||||
configManager = new ConfigManager(details.name);
|
|
||||||
for (NamedProperty<?> prop : props) {
|
|
||||||
configManager.property(prop.name, prop.prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(RenderScope scope) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean isEnabled();
|
|
||||||
|
|
||||||
public final void setEnabled(boolean e) {
|
|
||||||
onEnabled(e);
|
|
||||||
ModManager.updateEnabledModules();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void onEnabled(boolean e);
|
|
||||||
|
|
||||||
public final String getName() {
|
|
||||||
return details.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnIdentifier getIconTexture() {
|
|
||||||
return Textures.getModIcon(details.namespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigManager getConfig() {
|
|
||||||
return configManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return details.description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getTags() {
|
|
||||||
return details.tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return details.version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.saturnclient.modules;
|
|
||||||
|
|
||||||
public class ModuleDetails {
|
|
||||||
public String name;
|
|
||||||
public String namespace;
|
|
||||||
public String description;
|
|
||||||
public String version;
|
|
||||||
public String[] tags = {};
|
|
||||||
|
|
||||||
public ModuleDetails(String name, String namespace) {
|
|
||||||
this.name = name;
|
|
||||||
this.namespace = namespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleDetails name(String name) {
|
|
||||||
this.name = name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleDetails namespace(String namespace) {
|
|
||||||
this.namespace = namespace;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleDetails description(String description) {
|
|
||||||
this.description = description;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleDetails version(String version) {
|
|
||||||
this.version = version;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleDetails tags(String... tags) {
|
|
||||||
this.tags = tags;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnItemStack;
|
|
||||||
|
|
||||||
public interface ArmorDisplayInterface {
|
|
||||||
|
|
||||||
SaturnItemStack getMainHand();
|
|
||||||
|
|
||||||
SaturnItemStack getHelmet();
|
|
||||||
|
|
||||||
SaturnItemStack getChestplate();
|
|
||||||
|
|
||||||
SaturnItemStack getLeggings();
|
|
||||||
|
|
||||||
SaturnItemStack getBoots();
|
|
||||||
|
|
||||||
SaturnItemStack getDummyMainHand();
|
|
||||||
|
|
||||||
SaturnItemStack getDummyHelmet();
|
|
||||||
|
|
||||||
SaturnItemStack getDummyChestplate();
|
|
||||||
|
|
||||||
SaturnItemStack getDummyLeggings();
|
|
||||||
|
|
||||||
SaturnItemStack getDummyBoots();
|
|
||||||
|
|
||||||
boolean isEmpty(SaturnItemStack stack);
|
|
||||||
|
|
||||||
int getMaxDamage(SaturnItemStack stack);
|
|
||||||
|
|
||||||
int getDamage(SaturnItemStack stack);
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface AutoSprintInterface {
|
|
||||||
|
|
||||||
boolean hasPlayer();
|
|
||||||
|
|
||||||
boolean hasNetwork();
|
|
||||||
|
|
||||||
boolean isForwardPressed();
|
|
||||||
|
|
||||||
boolean isBackPressed();
|
|
||||||
|
|
||||||
boolean isSneaking();
|
|
||||||
|
|
||||||
boolean hasHorizontalCollision();
|
|
||||||
|
|
||||||
boolean isUsingItem();
|
|
||||||
|
|
||||||
void setSprinting(boolean sprinting);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface CoordinatesInterface {
|
|
||||||
|
|
||||||
int getPlayerX();
|
|
||||||
|
|
||||||
int getPlayerY();
|
|
||||||
|
|
||||||
int getPlayerZ();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface CrosshairInterface {
|
|
||||||
|
|
||||||
boolean isTargetingLivingEntity();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface DayCounterInterface {
|
|
||||||
|
|
||||||
long getDay();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface FpsInterface {
|
|
||||||
|
|
||||||
int getFps();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface FreelookInterface {
|
|
||||||
|
|
||||||
boolean isFirstPerson();
|
|
||||||
|
|
||||||
void setFirstPerson();
|
|
||||||
|
|
||||||
void setThirdPersonBack();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface HealthDisplayInterface {
|
|
||||||
|
|
||||||
float getPlayerHealth();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface KeystrokesInterface {
|
|
||||||
|
|
||||||
boolean isForwardPressed();
|
|
||||||
boolean isBackPressed();
|
|
||||||
boolean isLeftPressed();
|
|
||||||
boolean isRightPressed();
|
|
||||||
boolean isJumpPressed();
|
|
||||||
boolean isAttackPressed();
|
|
||||||
boolean isUsePressed();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface NametagsInterface {
|
|
||||||
|
|
||||||
public static interface EntityState {
|
|
||||||
|
|
||||||
String getCustomName();
|
|
||||||
|
|
||||||
float getHealth();
|
|
||||||
|
|
||||||
float getMaxHealth();
|
|
||||||
|
|
||||||
EntityType getEntityType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum EntityType {
|
|
||||||
PLAYER,
|
|
||||||
PASSIVE,
|
|
||||||
HOSTILE,
|
|
||||||
OTHER
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface PingInterface {
|
|
||||||
|
|
||||||
/** Returns current player ping in milliseconds */
|
|
||||||
int getPing();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
public interface SpeedometerInterface {
|
|
||||||
|
|
||||||
/** Returns the current player or vehicle velocity in blocks per tick */
|
|
||||||
Velocity getVelocity();
|
|
||||||
|
|
||||||
/** Returns true if player or vehicle is on ground */
|
|
||||||
boolean isOnGround();
|
|
||||||
|
|
||||||
class Velocity {
|
|
||||||
public final double x, y, z;
|
|
||||||
|
|
||||||
public Velocity(double x, double y, double z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package org.saturnclient.modules.interfaces;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnSprite;
|
|
||||||
|
|
||||||
public interface StatusEffectsInterface {
|
|
||||||
|
|
||||||
/** Returns a list of currently active effects */
|
|
||||||
List<Effect> getActiveEffects();
|
|
||||||
|
|
||||||
/** Returns a dummy list of effects for dummy rendering */
|
|
||||||
List<Effect> getDummyEffects();
|
|
||||||
|
|
||||||
/** Represents a single effect for rendering purposes */
|
|
||||||
class Effect {
|
|
||||||
private final SaturnSprite icon;
|
|
||||||
private final int durationSeconds;
|
|
||||||
private final boolean infinite;
|
|
||||||
private final boolean showIcon;
|
|
||||||
private final String infiniteText;
|
|
||||||
|
|
||||||
public Effect(SaturnSprite icon, int durationSeconds, boolean infinite, boolean showIcon, String infiniteText) {
|
|
||||||
this.icon = icon;
|
|
||||||
this.durationSeconds = durationSeconds;
|
|
||||||
this.infinite = infinite;
|
|
||||||
this.showIcon = showIcon;
|
|
||||||
this.infiniteText = infiniteText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnSprite getIcon() { return icon; }
|
|
||||||
public int getDurationSeconds() { return durationSeconds; }
|
|
||||||
public boolean isInfinite() { return infinite; }
|
|
||||||
public boolean shouldShowIcon() { return showIcon; }
|
|
||||||
public String getInfiniteText() { return infiniteText; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.ArmorDisplayInterface;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnItemStack;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class ArmorDisplay extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(40, 75);
|
|
||||||
private static Property<Boolean> useMainHand = Property.bool(true);
|
|
||||||
|
|
||||||
private final ArmorDisplayInterface minecraft;
|
|
||||||
|
|
||||||
public ArmorDisplay(ArmorDisplayInterface minecraft) {
|
|
||||||
super(new ModuleDetails("Armor Display", "armor")
|
|
||||||
.description("Displays armor durability")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
useMainHand.named("Use Main Hand"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderArmor(RenderScope scope,
|
|
||||||
SaturnItemStack mainHand,
|
|
||||||
SaturnItemStack helmet,
|
|
||||||
SaturnItemStack chestplate,
|
|
||||||
SaturnItemStack leggings,
|
|
||||||
SaturnItemStack boots) {
|
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
|
|
||||||
if (useMainHand.value && !minecraft.isEmpty(mainHand)) {
|
|
||||||
scope.drawItem(mainHand, 0, 15 * row);
|
|
||||||
renderHealth(scope, row, minecraft.getMaxDamage(mainHand), minecraft.getDamage(mainHand));
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minecraft.isEmpty(helmet)) {
|
|
||||||
scope.drawItem(helmet, 0, 15 * row);
|
|
||||||
renderHealth(scope, row, minecraft.getMaxDamage(helmet), minecraft.getDamage(helmet));
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minecraft.isEmpty(chestplate)) {
|
|
||||||
scope.drawItem(chestplate, 0, 15 * row);
|
|
||||||
renderHealth(scope, row, minecraft.getMaxDamage(chestplate), minecraft.getDamage(chestplate));
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minecraft.isEmpty(leggings)) {
|
|
||||||
scope.drawItem(leggings, 0, 15 * row);
|
|
||||||
renderHealth(scope, row, minecraft.getMaxDamage(leggings), minecraft.getDamage(leggings));
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minecraft.isEmpty(boots)) {
|
|
||||||
scope.drawItem(boots, 0, 15 * row);
|
|
||||||
renderHealth(scope, row, minecraft.getMaxDamage(boots), minecraft.getDamage(boots));
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderHealth(RenderScope scope, int i, int maxDamage, int damage) {
|
|
||||||
if (maxDamage > 0) {
|
|
||||||
scope.drawText(
|
|
||||||
0.5f,
|
|
||||||
"" + (maxDamage - damage),
|
|
||||||
17,
|
|
||||||
(15 * i) + 3,
|
|
||||||
dimensions.font.value,
|
|
||||||
dimensions.fgColor.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
renderArmor(scope,
|
|
||||||
minecraft.getMainHand(),
|
|
||||||
minecraft.getHelmet(),
|
|
||||||
minecraft.getChestplate(),
|
|
||||||
minecraft.getLeggings(),
|
|
||||||
minecraft.getBoots());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderArmor(scope,
|
|
||||||
minecraft.getDummyMainHand(),
|
|
||||||
minecraft.getDummyHelmet(),
|
|
||||||
minecraft.getDummyChestplate(),
|
|
||||||
minecraft.getDummyLeggings(),
|
|
||||||
minecraft.getDummyBoots());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.AutoSprintInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class AutoSprint extends Module {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
|
|
||||||
private final AutoSprintInterface minecraft;
|
|
||||||
|
|
||||||
public AutoSprint(AutoSprintInterface minecraft) {
|
|
||||||
super(
|
|
||||||
new ModuleDetails("Auto Sprint", "sprint")
|
|
||||||
.description("Makes the player always sprint")
|
|
||||||
.tags("Movement")
|
|
||||||
.version("v0.1.0"),
|
|
||||||
enabled.named("Enabled"));
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (!minecraft.hasPlayer() || !minecraft.hasNetwork()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minecraft.isForwardPressed()
|
|
||||||
&& !minecraft.isBackPressed()
|
|
||||||
&& !minecraft.isSneaking()
|
|
||||||
&& !minecraft.hasHorizontalCollision()
|
|
||||||
&& !minecraft.isUsingItem()) {
|
|
||||||
|
|
||||||
minecraft.setSprinting(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Clock extends Module implements HudMod {
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Integer> format = Property.select(0, "24 hour", "12 hour");
|
|
||||||
private static Property<Boolean> seconds = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
|
||||||
|
|
||||||
public Clock() {
|
|
||||||
super(new ModuleDetails("Clock", "clock")
|
|
||||||
.description("Displays the current real-world time")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
format.named("Format"),
|
|
||||||
seconds.named("Show seconds"),
|
|
||||||
dimensions.prop());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderClock(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
renderClock(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderClock(RenderScope scope) {
|
|
||||||
String text = "";
|
|
||||||
LocalTime currentTime = LocalTime.now();
|
|
||||||
|
|
||||||
switch (format.value) {
|
|
||||||
case 0:
|
|
||||||
if (seconds.value) {
|
|
||||||
text = currentTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
|
|
||||||
} else {
|
|
||||||
text = currentTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (seconds.value) {
|
|
||||||
text = currentTime.format(DateTimeFormatter.ofPattern("hh:mm:ss a"));
|
|
||||||
} else {
|
|
||||||
text = currentTime.format(DateTimeFormatter.ofPattern("hh:mm a"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.drawText(text,
|
|
||||||
0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
dimensions.height = 18 * text.split("\n").length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.CoordinatesInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Coordinates extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
|
|
||||||
private static Property<Integer> displayMethod = Property.select(
|
|
||||||
0,
|
|
||||||
"Flat",
|
|
||||||
"Flat annotated",
|
|
||||||
"Newline",
|
|
||||||
"Newline annotated");
|
|
||||||
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(40, 18);
|
|
||||||
|
|
||||||
private final CoordinatesInterface minecraft;
|
|
||||||
|
|
||||||
public Coordinates(CoordinatesInterface minecraft) {
|
|
||||||
super(new ModuleDetails("Coordinates", "coords")
|
|
||||||
.description("Displays your current coordinates")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
displayMethod.named("Display Method"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderCoords(532, 69, 253, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
int x = minecraft.getPlayerX();
|
|
||||||
int y = minecraft.getPlayerY();
|
|
||||||
int z = minecraft.getPlayerZ();
|
|
||||||
|
|
||||||
renderCoords(x, y, z, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderCoords(int x, int y, int z, RenderScope scope) {
|
|
||||||
|
|
||||||
String f = "%d %d %d";
|
|
||||||
|
|
||||||
switch (displayMethod.value) {
|
|
||||||
case 1:
|
|
||||||
f = "X: %d Y: %d Z: %d";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
f = "%d\n%d\n%d";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
f = "X: %d\nY: %d\nZ: %d";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
String text = String.format(f, x, y, z);
|
|
||||||
|
|
||||||
scope.drawText(
|
|
||||||
text,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
dimensions.font.value,
|
|
||||||
dimensions.fgColor.value);
|
|
||||||
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
dimensions.height = 18 * text.split("\n").length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.CrosshairInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Textures;
|
|
||||||
|
|
||||||
public class Crosshair extends Module {
|
|
||||||
|
|
||||||
public static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
|
|
||||||
private final CrosshairInterface minecraft;
|
|
||||||
|
|
||||||
public Crosshair(CrosshairInterface minecraft) {
|
|
||||||
super(
|
|
||||||
new ModuleDetails("Crosshair", "crosshair")
|
|
||||||
.description("Changes the crosshair if you're aiming at a entity")
|
|
||||||
.tags("Visuals", "Utility")
|
|
||||||
.version("v0.1.0"),
|
|
||||||
enabled.named("Enabled"));
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope scope) {
|
|
||||||
|
|
||||||
if (enabled.value && minecraft.isTargetingLivingEntity()) {
|
|
||||||
|
|
||||||
int scaledWidth = 15;
|
|
||||||
int scaledHeight = 15;
|
|
||||||
|
|
||||||
scope.drawTexture(
|
|
||||||
Textures.CROSSHAIR_RANGE,
|
|
||||||
(scope.getScaledWindowWidth() - scaledWidth) / 2,
|
|
||||||
(scope.getScaledWindowHeight() - scaledHeight) / 2,
|
|
||||||
0.0F,
|
|
||||||
0.0F,
|
|
||||||
scaledWidth,
|
|
||||||
scaledHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.DayCounterInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class DayCounter extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(40, 18);
|
|
||||||
|
|
||||||
private final DayCounterInterface minecraft;
|
|
||||||
|
|
||||||
long day = 0;
|
|
||||||
|
|
||||||
public DayCounter(DayCounterInterface minecraft) {
|
|
||||||
super(new ModuleDetails("DayCounter", "day")
|
|
||||||
.description("Displays the number of days that have passed")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderDay(271, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
day = minecraft.getDay();
|
|
||||||
renderDay(day, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderDay(long day, RenderScope scope) {
|
|
||||||
String text = "Day: " + day;
|
|
||||||
|
|
||||||
scope.drawText(
|
|
||||||
text,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
dimensions.font.value,
|
|
||||||
dimensions.fgColor.value);
|
|
||||||
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
dimensions.height = 18 * text.split("\n").length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.FpsInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Fps extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
|
||||||
|
|
||||||
private final FpsInterface minecraft;
|
|
||||||
|
|
||||||
public Fps(FpsInterface minecraft) {
|
|
||||||
super(new ModuleDetails("FPS Display", "fps")
|
|
||||||
.description("Displays current FPS")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
int fps = minecraft.getFps();
|
|
||||||
|
|
||||||
String text = fps + " FPS";
|
|
||||||
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
String text = "369 FPS";
|
|
||||||
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.FreelookInterface;
|
|
||||||
import org.saturnclient.config.manager.Key;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class Freelook extends Module {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Boolean> toggle = Property.bool(true);
|
|
||||||
|
|
||||||
public static Property<Integer> freelookKey = Property.keybinding(Key.GLFW_KEY_H);
|
|
||||||
|
|
||||||
public static boolean isFreeLooking = false;
|
|
||||||
private static boolean was1stPerson = false;
|
|
||||||
|
|
||||||
private final FreelookInterface minecraft;
|
|
||||||
|
|
||||||
public Freelook(FreelookInterface minecraft) {
|
|
||||||
super(
|
|
||||||
new ModuleDetails("Freelook", "freelook")
|
|
||||||
.description("Allows you to look around freely without moving your character")
|
|
||||||
.tags("Movement", "Camera")
|
|
||||||
.version("0.1.0"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
toggle.named("Toggle freelook"),
|
|
||||||
freelookKey.named("Freelook Keybinding"));
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
|
|
||||||
if (toggle.value) {
|
|
||||||
|
|
||||||
if (freelookKey.wasKeyPressed()) {
|
|
||||||
|
|
||||||
if (isFreeLooking) {
|
|
||||||
stopFreelook();
|
|
||||||
} else {
|
|
||||||
startFreelook();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (freelookKey.isKeyPressed()) {
|
|
||||||
|
|
||||||
if (!isFreeLooking) {
|
|
||||||
startFreelook();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (isFreeLooking) {
|
|
||||||
|
|
||||||
stopFreelook();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startFreelook() {
|
|
||||||
isFreeLooking = true;
|
|
||||||
|
|
||||||
was1stPerson = minecraft.isFirstPerson();
|
|
||||||
|
|
||||||
minecraft.setThirdPersonBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopFreelook() {
|
|
||||||
|
|
||||||
if (was1stPerson) {
|
|
||||||
minecraft.setFirstPerson();
|
|
||||||
}
|
|
||||||
|
|
||||||
isFreeLooking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class Fullbright extends Module {
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Integer> brightness = Property.integer(100);
|
|
||||||
|
|
||||||
public Fullbright() {
|
|
||||||
super(
|
|
||||||
new ModuleDetails("Fullbright", "fullbright")
|
|
||||||
.description("Allows you to see in the dark")
|
|
||||||
.tags("Camera")
|
|
||||||
.version("v0.1.0"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
brightness.named("Brightness %"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean shouldOverrideBrightness() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getBrightnessValue() {
|
|
||||||
return brightness.value / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.HealthDisplayInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class HealthDisplay extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Integer> displayMode = Property.select(0, "Health", "Hearts");
|
|
||||||
private static Property<Integer> decimals = Property.select(0, "0", "1", "2");
|
|
||||||
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(40, 18);
|
|
||||||
|
|
||||||
private final HealthDisplayInterface minecraft;
|
|
||||||
|
|
||||||
public HealthDisplay(HealthDisplayInterface minecraft) {
|
|
||||||
super(new ModuleDetails("Health display", "health")
|
|
||||||
.description("Displays your current health")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
displayMode.named("Display mode"),
|
|
||||||
decimals.named("Decimals"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderHealth(10, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
float health = minecraft.getPlayerHealth();
|
|
||||||
|
|
||||||
switch (displayMode.value) {
|
|
||||||
case 1:
|
|
||||||
health = health / 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderHealth(health, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderHealth(float health, RenderScope scope) {
|
|
||||||
|
|
||||||
String text = "";
|
|
||||||
|
|
||||||
switch (decimals.value) {
|
|
||||||
case 0:
|
|
||||||
text = String.format("%.0f ", health);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
text = String.format("%.1f ", health);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
text = String.format("%.2f ", health);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.drawText(
|
|
||||||
text,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
dimensions.font.value,
|
|
||||||
dimensions.fgColor.value
|
|
||||||
);
|
|
||||||
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
dimensions.height = 18 * text.split("\n").length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.KeystrokesInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class Keystrokes extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static final Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static final Property<Boolean> showMouse = Property.bool(true);
|
|
||||||
private static final Property<Boolean> showSpace = Property.bool(false);
|
|
||||||
|
|
||||||
private static final Property<Integer> clickBg = Property.color(0xFFCCCCCC);
|
|
||||||
private static final Property<Integer> clickFg = Property.color(0xFFFFFFFF);
|
|
||||||
|
|
||||||
private static final ModDimensions dimensions = new ModDimensions(78, 54);
|
|
||||||
|
|
||||||
private final KeystrokesInterface minecraft;
|
|
||||||
|
|
||||||
// Key states
|
|
||||||
private boolean w, a, s, d, lmb, rmb, space;
|
|
||||||
|
|
||||||
// Layout constants
|
|
||||||
private static final int KEY_SIZE = 24;
|
|
||||||
private static final int KEY_SPACING = 3;
|
|
||||||
private static final int MOUSE_WIDTH = 38;
|
|
||||||
private static final int MOUSE_HEIGHT = 24;
|
|
||||||
private static final int SPACE_HEIGHT = 19;
|
|
||||||
|
|
||||||
public Keystrokes(KeystrokesInterface minecraft) {
|
|
||||||
super(new ModuleDetails("Keystrokes", "keystrokes")
|
|
||||||
.description("Displays movement keystrokes")
|
|
||||||
.version("v0.2.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
showMouse.named("Show mouse clicks"),
|
|
||||||
showSpace.named("Show space"),
|
|
||||||
dimensions.prop(),
|
|
||||||
clickFg.named("Clicked fg"),
|
|
||||||
clickBg.named("Clicked bg"));
|
|
||||||
|
|
||||||
this.minecraft = minecraft;
|
|
||||||
|
|
||||||
dimensions.renderBackground = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
w = minecraft.isForwardPressed();
|
|
||||||
a = minecraft.isLeftPressed();
|
|
||||||
s = minecraft.isBackPressed();
|
|
||||||
d = minecraft.isRightPressed();
|
|
||||||
lmb = minecraft.isAttackPressed();
|
|
||||||
rmb = minecraft.isUsePressed();
|
|
||||||
space = minecraft.isJumpPressed();
|
|
||||||
|
|
||||||
updateHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateHeight() {
|
|
||||||
int height = KEY_SIZE * 2 + KEY_SPACING;
|
|
||||||
|
|
||||||
if (showSpace.value)
|
|
||||||
height += SPACE_HEIGHT + KEY_SPACING;
|
|
||||||
|
|
||||||
if (showMouse.value)
|
|
||||||
height += MOUSE_HEIGHT + KEY_SPACING;
|
|
||||||
|
|
||||||
dimensions.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
render(scope, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
render(scope, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void render(RenderScope scope, boolean live) {
|
|
||||||
|
|
||||||
int yOffset = 0;
|
|
||||||
|
|
||||||
// --- W ---
|
|
||||||
renderKey(scope, live && w, 'W', KEY_SIZE + KEY_SPACING, yOffset);
|
|
||||||
|
|
||||||
// --- A S D ---
|
|
||||||
yOffset += KEY_SIZE + KEY_SPACING;
|
|
||||||
|
|
||||||
renderKey(scope, live && a, 'A', 0, yOffset);
|
|
||||||
renderKey(scope, live && s, 'S', KEY_SIZE + KEY_SPACING, yOffset);
|
|
||||||
renderKey(scope, live && d, 'D', (KEY_SIZE + KEY_SPACING) * 2, yOffset);
|
|
||||||
|
|
||||||
yOffset += KEY_SIZE + KEY_SPACING;
|
|
||||||
|
|
||||||
// --- SPACE ---
|
|
||||||
if (showSpace.value) {
|
|
||||||
renderKeySpace(scope, live && space, 0, yOffset);
|
|
||||||
yOffset += SPACE_HEIGHT + KEY_SPACING;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- MOUSE ---
|
|
||||||
if (showMouse.value) {
|
|
||||||
renderKeyMouse(scope, live && lmb, "LMB", 0, yOffset);
|
|
||||||
renderKeyMouse(scope, live && rmb, "RMB", MOUSE_WIDTH + KEY_SPACING, yOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderKey(RenderScope scope, boolean pressed, char c, int x, int y) {
|
|
||||||
int bg = pressed ? clickBg.value : dimensions.bgColor.value;
|
|
||||||
int fg = pressed ? clickFg.value : dimensions.fgColor.value;
|
|
||||||
|
|
||||||
scope.drawRoundedRectangle(x, y, KEY_SIZE, KEY_SIZE, dimensions.radius.value, bg);
|
|
||||||
scope.drawText(0.6f, String.valueOf(c), x + 9, y + 7, dimensions.font.value, fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderKeyMouse(RenderScope scope, boolean pressed, String text, int x, int y) {
|
|
||||||
int bg = pressed ? clickBg.value : dimensions.bgColor.value;
|
|
||||||
int fg = pressed ? clickFg.value : dimensions.fgColor.value;
|
|
||||||
|
|
||||||
scope.drawRoundedRectangle(x, y, MOUSE_WIDTH, MOUSE_HEIGHT, dimensions.radius.value, bg);
|
|
||||||
scope.drawText(0.6f, text, x + 9, y + 7, dimensions.font.value, fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderKeySpace(RenderScope scope, boolean pressed, int x, int y) {
|
|
||||||
int bg = pressed ? clickBg.value : dimensions.bgColor.value;
|
|
||||||
int fg = pressed ? clickFg.value : dimensions.fgColor.value;
|
|
||||||
|
|
||||||
scope.drawRoundedRectangle(x, y, dimensions.width, SPACE_HEIGHT, dimensions.radius.value, bg);
|
|
||||||
|
|
||||||
int lineY = y + SPACE_HEIGHT / 2;
|
|
||||||
scope.drawRect(x + (dimensions.width - 30) / 2, lineY, 30, 1, fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.modules.interfaces.NametagsInterface;
|
|
||||||
|
|
||||||
public class Nametags extends Module {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Boolean> healthDisplay = Property.bool(false);
|
|
||||||
private static Property<Boolean> players = Property.bool(true);
|
|
||||||
private static Property<Boolean> hostile = Property.bool(false);
|
|
||||||
private static Property<Boolean> passive = Property.bool(false);
|
|
||||||
private static Property<Boolean> heartEmoji = Property.bool(true);
|
|
||||||
private static Property<Boolean> obfuscate = Property.bool(false);
|
|
||||||
private static Property<Integer> unit = Property.select(0, "Health", "Hearts");
|
|
||||||
private static Property<Integer> format = Property.select(0, "Value", "Value / Total", "%");
|
|
||||||
private static Property<Integer> nameColor = Property.select(15,
|
|
||||||
"Black","Dark Blue","Dark Green","Dark Aqua","Dark Red","Dark Purple","Gold","Gray",
|
|
||||||
"Dark Gray","Blue","Green","Aqua","Red","Light Purple","Yellow","White");
|
|
||||||
private static Property<Integer> healthColor = Property.select(12,
|
|
||||||
"Black","Dark Blue","Dark Green","Dark Aqua","Dark Red","Dark Purple","Gold","Gray",
|
|
||||||
"Dark Gray","Blue","Green","Aqua","Red","Light Purple","Yellow","White");
|
|
||||||
|
|
||||||
private static final String[] COLOR_CODES = {
|
|
||||||
"§0", "§1", "§2", "§3", "§4", "§5", "§6", "§7",
|
|
||||||
"§8", "§9", "§a", "§b", "§c", "§d", "§e", "§f"
|
|
||||||
};
|
|
||||||
|
|
||||||
public Nametags(NametagsInterface minecraft) {
|
|
||||||
super(new ModuleDetails("Nametags", "nametags")
|
|
||||||
.description("Allows you to modify entity nametags")
|
|
||||||
.tags("Camera", "Utility")
|
|
||||||
.version("0.1.0"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
healthDisplay.named("Display health"),
|
|
||||||
players.named("Players"),
|
|
||||||
hostile.named("Hostile"),
|
|
||||||
passive.named("Passive"),
|
|
||||||
heartEmoji.named("Heart emoji"),
|
|
||||||
obfuscate.named("Obfuscate enemy names"),
|
|
||||||
unit.named("Unit"),
|
|
||||||
format.named("Format"),
|
|
||||||
nameColor.named("Name color"),
|
|
||||||
healthColor.named("Health color"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
// Currently unused
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getHealthString(NametagsInterface.EntityState state, float health, float maxHealth) {
|
|
||||||
String ret = "";
|
|
||||||
|
|
||||||
switch (format.value) {
|
|
||||||
case 0: // value
|
|
||||||
ret = String.format("%.1f", health / (unit.value + 1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // value / total
|
|
||||||
ret = String.format("%.1f", health / (unit.value + 1)) + " / "
|
|
||||||
+ String.format("%.1f", maxHealth / (unit.value + 1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // %
|
|
||||||
ret = String.format("%.0f%%", (health / maxHealth) * 100);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getNametagString(NametagsInterface.EntityState state) {
|
|
||||||
if (state.getCustomName() == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!healthDisplay.value)
|
|
||||||
return state.getCustomName(); // name only
|
|
||||||
|
|
||||||
float health = state.getHealth();
|
|
||||||
float maxHealth = state.getMaxHealth();
|
|
||||||
NametagsInterface.EntityType type = state.getEntityType();
|
|
||||||
|
|
||||||
if (type == NametagsInterface.EntityType.PASSIVE && !passive.value)
|
|
||||||
return null;
|
|
||||||
if (type == NametagsInterface.EntityType.HOSTILE && !hostile.value)
|
|
||||||
return null;
|
|
||||||
if (type == NametagsInterface.EntityType.PLAYER && !players.value)
|
|
||||||
return null;
|
|
||||||
if (type == NametagsInterface.EntityType.OTHER)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (health < 0f || maxHealth < 0f || health > maxHealth)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
String hpColor = COLOR_CODES[healthColor.value];
|
|
||||||
String color = COLOR_CODES[nameColor.value];
|
|
||||||
String heart = heartEmoji.value ? " ❤" : "";
|
|
||||||
String obf = obfuscate.value ? "§k" : "";
|
|
||||||
String reset = "§r";
|
|
||||||
|
|
||||||
return color + obf + state.getCustomName() + reset + " " + hpColor
|
|
||||||
+ getHealthString(state, health, maxHealth) + heart;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean shouldReplaceName() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class NoFog extends Module {
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Boolean> liquids = Property.bool(false);
|
|
||||||
|
|
||||||
public NoFog() {
|
|
||||||
super(
|
|
||||||
new ModuleDetails("No Fog", "nofog")
|
|
||||||
.description("Stops fog from rendering")
|
|
||||||
.tags("Camera")
|
|
||||||
.version("v0.1.0"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
liquids.named("See through liquids"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static for the mixin
|
|
||||||
public static boolean isActive() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean liquids() {
|
|
||||||
return liquids.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.modules.interfaces.PingInterface;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Ping extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
|
||||||
|
|
||||||
private final PingInterface pingProvider;
|
|
||||||
|
|
||||||
public Ping(PingInterface pingProvider) {
|
|
||||||
super(new ModuleDetails("Ping Display", "ping")
|
|
||||||
.description("Displays ping")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.pingProvider = pingProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
int ping = pingProvider.getPing();
|
|
||||||
String text = ping + " ms";
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
String text = "10 ms";
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.modules.interfaces.SpeedometerInterface;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Speedometer extends Module implements HudMod {
|
|
||||||
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Integer> axis = Property.select(1, "Absolute", "X axis", "Y axis");
|
|
||||||
private static Property<Integer> unitText = Property.select(0, "None", "Blocks/s", "blocks/s", "b/s");
|
|
||||||
private static Property<Boolean> speedText = Property.bool(true);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(40, 18);
|
|
||||||
|
|
||||||
private final SpeedometerInterface provider;
|
|
||||||
private double speed = 0.;
|
|
||||||
|
|
||||||
public Speedometer(SpeedometerInterface provider) {
|
|
||||||
super(new ModuleDetails("Speedometer", "speed")
|
|
||||||
.description("Displays your current speed")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
axis.named("Speed type"),
|
|
||||||
unitText.named("Unit text"),
|
|
||||||
speedText.named("Show speed text"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderSpeed(2.71, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
SpeedometerInterface.Velocity velocity = provider.getVelocity();
|
|
||||||
boolean onGround = provider.isOnGround();
|
|
||||||
|
|
||||||
double y = onGround ? 0.0 : velocity.y;
|
|
||||||
|
|
||||||
switch (axis.value) {
|
|
||||||
case 0: // Absolute
|
|
||||||
speed = Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(y, 2) + Math.pow(velocity.z, 2));
|
|
||||||
break;
|
|
||||||
case 1: // X axis
|
|
||||||
speed = Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(velocity.z, 2));
|
|
||||||
break;
|
|
||||||
case 2: // Y axis
|
|
||||||
speed = Math.abs(y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSpeed(speed * 20, scope); // blocks/tick to blocks/s
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderSpeed(double speed, RenderScope scope) {
|
|
||||||
String text = String.format("%.2f ", speed);
|
|
||||||
|
|
||||||
switch (unitText.value) {
|
|
||||||
case 1 -> text += "Blocks/s";
|
|
||||||
case 2 -> text += "blocks/s";
|
|
||||||
case 3 -> text += "b/s";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (speedText.value) {
|
|
||||||
text = "Speed: " + text;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
dimensions.height = 18 * text.split("\n").length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.modules.interfaces.StatusEffectsInterface;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class StatusEffects extends Module implements HudMod {
|
|
||||||
|
|
||||||
public static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(60, 0);
|
|
||||||
|
|
||||||
private final StatusEffectsInterface provider;
|
|
||||||
|
|
||||||
public StatusEffects(StatusEffectsInterface provider) {
|
|
||||||
super(new ModuleDetails("Status effects", "effect")
|
|
||||||
.description("Displays status effects")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
dimensions.prop());
|
|
||||||
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderEffects(RenderScope scope, List<StatusEffectsInterface.Effect> effects) {
|
|
||||||
int row = 0;
|
|
||||||
|
|
||||||
for (StatusEffectsInterface.Effect effect : effects) {
|
|
||||||
if (!effect.shouldShowIcon()) continue;
|
|
||||||
|
|
||||||
scope.drawSpriteStretched(effect.getIcon(), 0, 18 * row, 16, 16);
|
|
||||||
scope.drawText(0.5f, getDurationAsString(effect), 18, 18 * row + 3, dimensions.font.value, -1);
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
dimensions.height = 18 * row;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
renderEffects(scope, provider.getActiveEffects());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
renderEffects(scope, provider.getDummyEffects());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDurationAsString(StatusEffectsInterface.Effect effect) {
|
|
||||||
if (effect.isInfinite()) {
|
|
||||||
return effect.getInfiniteText();
|
|
||||||
}
|
|
||||||
|
|
||||||
int totalSeconds = effect.getDurationSeconds();
|
|
||||||
if (totalSeconds >= 3600) {
|
|
||||||
return totalSeconds / 3600 + "h";
|
|
||||||
} else if (totalSeconds >= 60) {
|
|
||||||
int minutes = totalSeconds / 60;
|
|
||||||
int seconds = totalSeconds % 60;
|
|
||||||
return String.format("%d:%02d", minutes, seconds);
|
|
||||||
} else {
|
|
||||||
return totalSeconds + "s";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.HudMod;
|
|
||||||
import org.saturnclient.modules.ModDimensions;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Tps extends Module implements HudMod {
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
|
||||||
|
|
||||||
private static long lastWorldAge = -1;
|
|
||||||
private static long lastRealTime = -1;
|
|
||||||
private static double currentTps = 20.0;
|
|
||||||
|
|
||||||
private static final int SAMPLE_COUNT = 2;
|
|
||||||
private static final double[] samples = new double[SAMPLE_COUNT];
|
|
||||||
static {
|
|
||||||
java.util.Arrays.fill(samples, 20.0);
|
|
||||||
}
|
|
||||||
private static int sampleIndex = 0;
|
|
||||||
private static int samplesFilled = 0;
|
|
||||||
|
|
||||||
public Tps() {
|
|
||||||
super(new ModuleDetails("TPS Display", "tps")
|
|
||||||
.description("Displays the TPS")
|
|
||||||
.version("v0.1.0")
|
|
||||||
.tags("Utility"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
dimensions.prop());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onTimePacket(long worldAge) {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (lastWorldAge != -1 && lastRealTime != -1) {
|
|
||||||
long tickDelta = worldAge - lastWorldAge;
|
|
||||||
long timeDelta = now - lastRealTime;
|
|
||||||
|
|
||||||
if (timeDelta > 0 && tickDelta > 0) {
|
|
||||||
double sample = (tickDelta / (double) timeDelta) * 1000.0;
|
|
||||||
sample = Math.min(sample, 20.0);
|
|
||||||
|
|
||||||
samples[sampleIndex % SAMPLE_COUNT] = sample;
|
|
||||||
sampleIndex++;
|
|
||||||
samplesFilled = Math.min(samplesFilled + 1, SAMPLE_COUNT);
|
|
||||||
|
|
||||||
double sum = 0;
|
|
||||||
for (int i = 0; i < samplesFilled; i++)
|
|
||||||
sum += samples[i];
|
|
||||||
currentTps = sum / samplesFilled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastWorldAge = worldAge;
|
|
||||||
lastRealTime = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reset() {
|
|
||||||
lastWorldAge = -1;
|
|
||||||
lastRealTime = -1;
|
|
||||||
currentTps = 20.0;
|
|
||||||
sampleIndex = 0;
|
|
||||||
samplesFilled = SAMPLE_COUNT;
|
|
||||||
for (int i = 0; i < SAMPLE_COUNT; i++)
|
|
||||||
samples[i] = 20.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderHud(RenderScope scope) {
|
|
||||||
String text = String.format("%.1f TPS", currentTps);
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderDummy(RenderScope scope) {
|
|
||||||
String text = "20.0 TPS";
|
|
||||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
|
||||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModDimensions getDimensions() {
|
|
||||||
return dimensions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.saturnclient.modules.mods;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.modules.ModuleDetails;
|
|
||||||
import org.saturnclient.config.manager.Key;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
|
|
||||||
public class Zoom extends Module {
|
|
||||||
private static Property<Boolean> enabled = Property.bool(false);
|
|
||||||
private static Property<Boolean> toggle = Property.bool(false);
|
|
||||||
public static Property<Integer> zoomKey = Property.keybinding(Key.GLFW_KEY_C);
|
|
||||||
public static Property<Float> zoomLevel = Property.floatProp(3.0f);
|
|
||||||
|
|
||||||
public static boolean isZooming = false;
|
|
||||||
|
|
||||||
public Zoom() {
|
|
||||||
super(
|
|
||||||
new ModuleDetails("Zoom", "zoom")
|
|
||||||
.description("Allows you to zoom in for a closer view")
|
|
||||||
.tags("Camera", "Utility")
|
|
||||||
.version("0.1.0"),
|
|
||||||
enabled.named("Enabled"),
|
|
||||||
toggle.named("Toggle zoom"),
|
|
||||||
zoomKey.named("Zoom Keybinding"),
|
|
||||||
zoomLevel.named("Zoom Level"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (toggle.value) {
|
|
||||||
if (zoomKey.wasKeyPressed()) {
|
|
||||||
isZooming = !isZooming;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
isZooming = zoomKey.isKeyPressed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getZoomLevel() {
|
|
||||||
return zoomLevel.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean shouldZoom() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnabled(boolean e) {
|
|
||||||
enabled.value = e;
|
|
||||||
if (!e) {
|
|
||||||
isZooming = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.anim.Animation;
|
|
||||||
|
|
||||||
public class Element {
|
|
||||||
public int x;
|
|
||||||
public int y;
|
|
||||||
public int width;
|
|
||||||
public int height;
|
|
||||||
public float opacity = 1.0f;
|
|
||||||
public boolean focused;
|
|
||||||
public Animation animation;
|
|
||||||
public float scale = 1.0f;
|
|
||||||
public Integer duration = null; // Element duration, will fade out if not null
|
|
||||||
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void charTyped(char typedChar) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playAnimationFrame(long elapsed) {
|
|
||||||
if (this.animation != null && elapsed >= this.animation.delay) {
|
|
||||||
this.animation.tick(this.animation.curve
|
|
||||||
.apply(Math.min(1.0, (double) (elapsed - this.animation.delay) / this.animation.duration)), this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element dimensions(int width, int height) {
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element position(int x, int y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element centerHorizontal(int w, int h, int offsetX, int offsetY) {
|
|
||||||
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
|
||||||
this.y = offsetY;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element center(int w, int h) {
|
|
||||||
this.centerOffset(w, h, 0, 0);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element centerOffset(int w, int h, int offsetX, int offsetY) {
|
|
||||||
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
|
||||||
this.y = (h - (int) (height * scale)) / 2 + offsetY;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element animation(Animation animation) {
|
|
||||||
this.animation = animation;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element scale(float scale) {
|
|
||||||
this.scale = scale;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
public class ElementContext {
|
|
||||||
public int mouseX, mouseY;
|
|
||||||
public int elementWidth, elementHeight;
|
|
||||||
public float elementScale;
|
|
||||||
public long elapsed;
|
|
||||||
|
|
||||||
public ElementContext(long elapsed, int mouseX, int mouseY, Element e) {
|
|
||||||
this.mouseX = mouseX - e.x;
|
|
||||||
this.mouseY = mouseY - e.y;
|
|
||||||
this.elementWidth = e.width;
|
|
||||||
this.elementHeight = e.height;
|
|
||||||
this.elementScale = e.scale;
|
|
||||||
this.elapsed = elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHovering() {
|
|
||||||
return Utils.isHovering(mouseX, mouseY, elementWidth, elementHeight, elementScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHovering(int x, int y, int width, int height) {
|
|
||||||
return Utils.isHovering(mouseX - x, mouseY - y, width, height, elementScale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class ElementRenderer {
|
|
||||||
public static ElementRenderer INSTANCE;
|
|
||||||
|
|
||||||
public abstract void draw(List<Element> elements, Element element);
|
|
||||||
|
|
||||||
public abstract void render(List<Element> elements, long elapsed, RenderScope renderScope, int mouseX, int mouseY);
|
|
||||||
|
|
||||||
public abstract void mouseClicked(List<Element> elements, double mouseX, double mouseY, int button);
|
|
||||||
|
|
||||||
public abstract void mouseScrolled(
|
|
||||||
List<Element> elements,
|
|
||||||
double mouseX,
|
|
||||||
double mouseY,
|
|
||||||
double horizontalAmount,
|
|
||||||
double verticalAmount);
|
|
||||||
|
|
||||||
public abstract void keyPressed(List<Element> elements, int keyCode, int scanCode, int modifiers);
|
|
||||||
|
|
||||||
public abstract void mouseDragged(List<Element> elements, double mouseX, double mouseY, int button, double deltaX,
|
|
||||||
double deltaY);
|
|
||||||
|
|
||||||
public abstract void mouseReleased(List<Element> elements, double mouseX, double mouseY, int button);
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnItemStack;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnSprite;
|
|
||||||
import org.saturnclient.common.minecraft.render.IMatrixStack;
|
|
||||||
|
|
||||||
public interface RenderScope {
|
|
||||||
public IMatrixStack getMatrixStack();
|
|
||||||
|
|
||||||
public void setOpacity(float alpha);
|
|
||||||
|
|
||||||
public int getColor(int color);
|
|
||||||
|
|
||||||
public void drawRect(int x, int y, int width, int height, int color);
|
|
||||||
|
|
||||||
public void drawText(String text, int x, int y, int font, int color);
|
|
||||||
|
|
||||||
public void drawText(float scale, String text, int x, int y, int font, int color);
|
|
||||||
|
|
||||||
public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color);
|
|
||||||
|
|
||||||
public int getScaledWindowWidth();
|
|
||||||
|
|
||||||
public int getScaledWindowHeight();
|
|
||||||
|
|
||||||
/* Saturn common sprites */
|
|
||||||
public void drawTexture(SaturnIdentifier sprite, int x, int y, float u, float v, int width, int height, int color);
|
|
||||||
|
|
||||||
public void drawTexture(SaturnIdentifier sprite, int x, int y, float u, float v, int width, int height);
|
|
||||||
|
|
||||||
public void drawTexture(SaturnIdentifier sprite, int x, int y, float u, float v, int width, int height,
|
|
||||||
int regionWith,
|
|
||||||
int regionHeight, int textureWidth, int textureHeight);
|
|
||||||
|
|
||||||
public void drawTexture(SaturnIdentifier sprite, int x, int y, float u, float v, int width, int height,
|
|
||||||
int regionWidth,
|
|
||||||
int regionHeight, int textureWidth, int textureHeight, int color);
|
|
||||||
|
|
||||||
public void enableScissor(int x1, int y1, int x2, int y2);
|
|
||||||
|
|
||||||
public void disableScissor();
|
|
||||||
|
|
||||||
public boolean scissorContains(int x, int y);
|
|
||||||
|
|
||||||
public void draw();
|
|
||||||
|
|
||||||
public void drawItem(SaturnItemStack item, int x, int y);
|
|
||||||
|
|
||||||
public void drawItem(SaturnItemStack stack, int x, int y, int seed);
|
|
||||||
|
|
||||||
public void drawItem(SaturnItemStack stack, int x, int y, int seed, int z);
|
|
||||||
|
|
||||||
public void drawItemWithoutEntity(SaturnItemStack stack, int x, int y);
|
|
||||||
|
|
||||||
public void drawItemWithoutEntity(SaturnItemStack stack, int x, int y, int seed);
|
|
||||||
|
|
||||||
public void drawSpriteStretched(SaturnSprite sprite, int x, int y, int width, int height);
|
|
||||||
|
|
||||||
public void drawSpriteStretched(SaturnSprite sprite, int x, int y, int width, int height, int color);
|
|
||||||
|
|
||||||
public void fill(int x1, int y1, int x2, int y2, int color);
|
|
||||||
|
|
||||||
public void fill(int x1, int y1, int x2, int y2, int z, int color);
|
|
||||||
|
|
||||||
public void drawBorder(int x, int y, int width, int height, int color);
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class SaturnScreen {
|
|
||||||
public static interface ScreenProvider {
|
|
||||||
public void close();
|
|
||||||
|
|
||||||
public int getWidth();
|
|
||||||
|
|
||||||
public int getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
// General
|
|
||||||
public int width;
|
|
||||||
public int height;
|
|
||||||
public String title;
|
|
||||||
|
|
||||||
// Saturn Screen
|
|
||||||
public List<Element> elements = new ArrayList<>();
|
|
||||||
public float backgroundOpacity = 1.0f;
|
|
||||||
protected Instant start = null;
|
|
||||||
public int backgroundBlur = 10;
|
|
||||||
|
|
||||||
// Provider
|
|
||||||
public ScreenProvider provider;
|
|
||||||
|
|
||||||
public SaturnScreen(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void init() {
|
|
||||||
elements.clear();
|
|
||||||
width = provider.getWidth();
|
|
||||||
height = provider.getHeight();
|
|
||||||
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void ui();
|
|
||||||
|
|
||||||
public void draw(Element element) {
|
|
||||||
ElementRenderer.INSTANCE.draw(elements, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------
|
|
||||||
// Rendering
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
public void render(RenderScope renderScope, int mouseX, int mouseY, float delta, long elapsed) {
|
|
||||||
renderScope.getMatrixStack().push();
|
|
||||||
|
|
||||||
renderScope.getMatrixStack().scale(0.5f, 0.5f, 0.5f);
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.render(new ArrayList<>(elements), elapsed, renderScope, mouseX, mouseY);
|
|
||||||
|
|
||||||
renderScope.getMatrixStack().pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------
|
|
||||||
// Events
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
mouseX *= 2;
|
|
||||||
mouseY *= 2;
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.mouseClicked(elements, mouseX, mouseY, button);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
|
||||||
mouseX *= 2;
|
|
||||||
mouseY *= 2;
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.mouseDragged(elements, mouseX, mouseY, button, deltaX, deltaY);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
|
||||||
mouseX *= 2;
|
|
||||||
mouseY *= 2;
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.mouseReleased(elements, mouseX, mouseY, button);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean mouseScrolled(
|
|
||||||
double mouseX,
|
|
||||||
double mouseY,
|
|
||||||
double horizontalAmount,
|
|
||||||
double verticalAmount) {
|
|
||||||
mouseX *= 2;
|
|
||||||
mouseY *= 2;
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.mouseScrolled(elements, mouseX, mouseY, horizontalAmount, verticalAmount);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resize(int width, int height) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
ElementRenderer.INSTANCE.keyPressed(elements, keyCode, scanCode, modifiers);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldPause() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClose() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.Key;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
public static boolean isHovering(int mouseX, int mouseY, int elementWidth, int elementHeight, float elementScale) {
|
|
||||||
return mouseX >= 0 &&
|
|
||||||
mouseX <= (elementWidth * elementScale) &&
|
|
||||||
mouseY >= 0 &&
|
|
||||||
mouseY <= (elementHeight * elementScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char getCharFromKey(int keyCode, int modifiers) {
|
|
||||||
boolean shift = (modifiers & Key.GLFW_MOD_SHIFT) != 0;
|
|
||||||
|
|
||||||
// A-Z
|
|
||||||
if (keyCode >= Key.GLFW_KEY_A && keyCode <= Key.GLFW_KEY_Z) {
|
|
||||||
return (char) (shift
|
|
||||||
? 'A' + (keyCode - Key.GLFW_KEY_A)
|
|
||||||
: 'a' + (keyCode - Key.GLFW_KEY_A));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0-9
|
|
||||||
if (keyCode >= Key.GLFW_KEY_0 && keyCode <= Key.GLFW_KEY_9) {
|
|
||||||
return shift
|
|
||||||
? ")!@#$%^&*(".charAt(keyCode - Key.GLFW_KEY_0)
|
|
||||||
: (char) ('0' + (keyCode - Key.GLFW_KEY_0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special characters
|
|
||||||
return switch (keyCode) {
|
|
||||||
case Key.GLFW_KEY_SPACE -> ' ';
|
|
||||||
case Key.GLFW_KEY_PERIOD -> shift ? '>' : '.';
|
|
||||||
case Key.GLFW_KEY_COMMA -> shift ? '<' : ',';
|
|
||||||
case Key.GLFW_KEY_MINUS -> shift ? '_' : '-';
|
|
||||||
case Key.GLFW_KEY_EQUAL -> shift ? '+' : '=';
|
|
||||||
case Key.GLFW_KEY_SEMICOLON -> shift ? ':' : ';';
|
|
||||||
case Key.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\'';
|
|
||||||
case Key.GLFW_KEY_SLASH -> shift ? '?' : '/';
|
|
||||||
case Key.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\';
|
|
||||||
case Key.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '[';
|
|
||||||
case Key.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']';
|
|
||||||
case Key.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`';
|
|
||||||
default -> '\0';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T getOrNull(List<T> list, int index) {
|
|
||||||
return (index >= 0 && index < list.size()) ? list.get(index) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public static void notify(NotificationKind kind, String title, String toast) {
|
|
||||||
// if (SaturnClient.client.currentScreen instanceof SaturnScreen) {
|
|
||||||
// ((SaturnScreen) SaturnClient.client.currentScreen)
|
|
||||||
// .draw(new Notification(SaturnClient.client.currentScreen.width,
|
|
||||||
// SaturnClient.client.currentScreen.height, kind,
|
|
||||||
// title, toast));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
|
|
||||||
public abstract class Animation {
|
|
||||||
public int duration;
|
|
||||||
public int delay = 0;
|
|
||||||
public Function<Double, Double> curve = Curve::easeInOutCubic;
|
|
||||||
|
|
||||||
Animation(AnimationConfig config) {
|
|
||||||
this.duration = config.duration.value;
|
|
||||||
switch (config.curve.value) {
|
|
||||||
case 0:
|
|
||||||
this.curve = Curve::easeInOutCubic;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
this.curve = Curve::easeOutCubic;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this.curve = Curve::easeInOutBack;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Animation(int duration) {
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void tick(double progress, Element element);
|
|
||||||
|
|
||||||
public abstract void init(Element element);
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
public class Curve {
|
|
||||||
public static double easeOutCubic(double x) {
|
|
||||||
return 1 - Math.pow(1 - x, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double easeInOutCubic(double x) {
|
|
||||||
return (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double easeInOutBack(double x) {
|
|
||||||
double c1 = 2.5;
|
|
||||||
double c2 = c1 * 1.525;
|
|
||||||
|
|
||||||
if (x < 0.5) {
|
|
||||||
return (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2;
|
|
||||||
} else {
|
|
||||||
return (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (2 * x - 2) + c2) + 2) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
|
|
||||||
public class Fade extends Animation {
|
|
||||||
float targetOpacity;
|
|
||||||
|
|
||||||
public Fade(int duration) {
|
|
||||||
super(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fade(AnimationConfig config) {
|
|
||||||
super(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(double progress, Element element) {
|
|
||||||
element.opacity = Math.max(0.1f, targetOpacity * (float) progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Element element) {
|
|
||||||
targetOpacity = element.opacity;
|
|
||||||
element.opacity = 0.1f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
|
|
||||||
public class FadeOut extends Animation {
|
|
||||||
float targetOpacity;
|
|
||||||
|
|
||||||
public FadeOut(int duration) {
|
|
||||||
super(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FadeOut(AnimationConfig config) {
|
|
||||||
super(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(double progress, Element element) {
|
|
||||||
element.opacity = targetOpacity - (float) progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Element element) {
|
|
||||||
targetOpacity = element.opacity;
|
|
||||||
// element.opacity = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
|
|
||||||
public class SlideFade extends Animation {
|
|
||||||
public Fade fade;
|
|
||||||
public SlideY slideY;
|
|
||||||
|
|
||||||
public SlideFade(int duration, int offset) {
|
|
||||||
super(duration);
|
|
||||||
this.fade = new Fade(duration);
|
|
||||||
this.slideY = new SlideY(duration, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideFade(AnimationConfig config, int offset) {
|
|
||||||
super(config);
|
|
||||||
this.fade = new Fade(duration);
|
|
||||||
this.slideY = new SlideY(duration, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(double progress, Element element) {
|
|
||||||
fade.delay = this.delay;
|
|
||||||
fade.duration = this.duration;
|
|
||||||
|
|
||||||
slideY.delay = this.delay;
|
|
||||||
slideY.duration = this.duration;
|
|
||||||
|
|
||||||
fade.tick(progress, element);
|
|
||||||
slideY.tick(progress, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Element element) {
|
|
||||||
fade.init(element);
|
|
||||||
slideY.init(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
|
|
||||||
public class SlideX extends Animation {
|
|
||||||
int offset = 20;
|
|
||||||
double startX;
|
|
||||||
|
|
||||||
public SlideX(AnimationConfig config) {
|
|
||||||
super(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideX(AnimationConfig config, int offset) {
|
|
||||||
super(config);
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideX(int duration) {
|
|
||||||
super(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideX(int duration, int offset) {
|
|
||||||
super(duration);
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Element element) {
|
|
||||||
startX = element.x - offset;
|
|
||||||
element.x = (int) startX;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(double progress, Element element) {
|
|
||||||
double currentX = startX + offset * progress;
|
|
||||||
element.x = (int) currentX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.saturnclient.ui.anim;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
|
|
||||||
public class SlideY extends Animation {
|
|
||||||
int offset = 20;
|
|
||||||
double startY;
|
|
||||||
|
|
||||||
public SlideY(AnimationConfig config) {
|
|
||||||
super(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideY(AnimationConfig config, int offset) {
|
|
||||||
super(config);
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideY(int duration) {
|
|
||||||
super(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlideY(int duration, int offset) {
|
|
||||||
super(duration);
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Element element) {
|
|
||||||
startY = element.y - offset;
|
|
||||||
element.y = (int) startY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(double progress, Element element) {
|
|
||||||
double currentY = startY + offset * progress;
|
|
||||||
element.y = (int) currentY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class CosmeticPreview extends Element {
|
|
||||||
static int padding = 14;
|
|
||||||
|
|
||||||
SaturnIdentifier sprite;
|
|
||||||
private Runnable onClick;
|
|
||||||
private boolean isSelected;
|
|
||||||
|
|
||||||
public CosmeticPreview(boolean isSelected, SaturnIdentifier sprite, Runnable onClick) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
this.onClick = onClick;
|
|
||||||
this.isSelected = isSelected;
|
|
||||||
|
|
||||||
this.width = 50;
|
|
||||||
this.height = 111;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
|
||||||
isSelected ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
|
||||||
|
|
||||||
int texWidth = width - padding;
|
|
||||||
int texHeight = height - padding;
|
|
||||||
|
|
||||||
renderScope.drawTexture(sprite, padding / 2, padding / 2, 0, 0, texWidth, texHeight,
|
|
||||||
Theme.FOREGROUND.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
if (onClick != null) {
|
|
||||||
onClick.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.ElementRenderer;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.Utils;
|
|
||||||
|
|
||||||
public class ElementRendererImpl extends ElementRenderer {
|
|
||||||
public void draw(List<Element> elements, Element element) {
|
|
||||||
synchronized (elements) {
|
|
||||||
elements.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.animation != null) {
|
|
||||||
element.animation.init(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(List<Element> elements, long elapsed, RenderScope renderScope, int mouseX, int mouseY) {
|
|
||||||
for (Element element : elements) {
|
|
||||||
element.playAnimationFrame(elapsed);
|
|
||||||
|
|
||||||
renderScope.getMatrixStack().push();
|
|
||||||
renderScope.setOpacity(element.opacity);
|
|
||||||
renderScope.getMatrixStack().translate(element.x, element.y, 0);
|
|
||||||
renderScope.getMatrixStack().scale(element.scale, element.scale, 1.0f);
|
|
||||||
element.render(renderScope, new ElementContext(elapsed, mouseX, mouseY, element));
|
|
||||||
renderScope.getMatrixStack().pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseClicked(List<Element> elements, double mouseX, double mouseY, int button) {
|
|
||||||
if (button == 0) {
|
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
|
||||||
element.focused = false;
|
|
||||||
|
|
||||||
int adjustedMouseX = (int) mouseX - element.x;
|
|
||||||
int adjustedMouseY = (int) mouseY - element.y;
|
|
||||||
|
|
||||||
element.mouseClicked(adjustedMouseX * element.scale, adjustedMouseY * element.scale, button);
|
|
||||||
|
|
||||||
if (element.opacity > 0 && Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width,
|
|
||||||
element.height, element.scale)) {
|
|
||||||
element.focused = true;
|
|
||||||
element.click((int) (adjustedMouseX * element.scale), (int) (adjustedMouseY * element.scale));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseScrolled(
|
|
||||||
List<Element> elements,
|
|
||||||
double mouseX,
|
|
||||||
double mouseY,
|
|
||||||
double horizontalAmount,
|
|
||||||
double verticalAmount) {
|
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
|
||||||
if (Utils.isHovering((int) mouseX - element.x, (int) mouseY - element.y, element.width, element.height,
|
|
||||||
element.scale)) {
|
|
||||||
element.scroll(
|
|
||||||
(int) mouseX - element.x,
|
|
||||||
(int) mouseY - element.y,
|
|
||||||
horizontalAmount,
|
|
||||||
verticalAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void keyPressed(List<Element> elements, int keyCode, int scanCode, int modifiers) {
|
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
|
||||||
if (element.focused && element.opacity > 0) {
|
|
||||||
element.keyPressed(keyCode, scanCode, modifiers);
|
|
||||||
|
|
||||||
char typedChar = Utils.getCharFromKey(keyCode, modifiers);
|
|
||||||
if (typedChar != '\0') {
|
|
||||||
element.charTyped(typedChar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseDragged(List<Element> elements, double mouseX, double mouseY, int button, double deltaX,
|
|
||||||
double deltaY) {
|
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
|
||||||
element.mouseDragged(mouseX - element.x, mouseY - element.y, button, deltaX, deltaY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseReleased(List<Element> elements, double mouseX, double mouseY, int button) {
|
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
|
||||||
element.mouseReleased(mouseX - element.x, mouseY - element.y, button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.Utils;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
import org.saturnclient.ui.resources.Textures;
|
|
||||||
import org.saturnclient.ui.screens.ConfigEditor;
|
|
||||||
|
|
||||||
public class SaturnModule extends Element {
|
|
||||||
|
|
||||||
private final Module mod;
|
|
||||||
|
|
||||||
static int p = 10; // padding
|
|
||||||
static int s = 14; // settings icon size
|
|
||||||
static int expand = 5; // settings icon click area
|
|
||||||
|
|
||||||
public SaturnModule(Module mod) {
|
|
||||||
this.mod = mod;
|
|
||||||
this.width = 160;
|
|
||||||
this.height = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
boolean hovered = ctx.isHovering();
|
|
||||||
boolean enabled = mod.isEnabled();
|
|
||||||
|
|
||||||
int iconX = width - s - p;
|
|
||||||
int iconY = height - s - p;
|
|
||||||
|
|
||||||
boolean settingsHover = ctx.isHovering(
|
|
||||||
getSettingsX(),
|
|
||||||
getSettingsY(),
|
|
||||||
getSettingsHitBox(),
|
|
||||||
getSettingsHitBox());
|
|
||||||
|
|
||||||
// Resolve theme colors
|
|
||||||
int bgColor = Theme.PRIMARY.value;
|
|
||||||
int fgColor = hovered && !settingsHover ? Theme.ACCENT.value : Theme.PRIMARY_FG.value;
|
|
||||||
|
|
||||||
int iconBg = enabled ? Theme.ACCENT.value : Theme.PRIMARY.value;
|
|
||||||
int iconFg = enabled ? Theme.ACCENT_FG.value : fgColor;
|
|
||||||
|
|
||||||
int settingsColor = settingsHover
|
|
||||||
? Theme.ACCENT.value
|
|
||||||
: Theme.withAlpha(160, fgColor);
|
|
||||||
|
|
||||||
int h = height - (p * 2);
|
|
||||||
|
|
||||||
// Main background
|
|
||||||
renderScope.drawRoundedRectangle(
|
|
||||||
0, 0,
|
|
||||||
width, height,
|
|
||||||
Theme.WIDGET_RADIUS.value,
|
|
||||||
bgColor);
|
|
||||||
|
|
||||||
// Icon background
|
|
||||||
renderScope.drawRoundedRectangle(
|
|
||||||
p, p,
|
|
||||||
h, h,
|
|
||||||
Theme.WIDGET_RADIUS.value,
|
|
||||||
iconBg);
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
renderScope.drawTexture(
|
|
||||||
mod.getIconTexture(),
|
|
||||||
p + (p / 2),
|
|
||||||
p + (p / 2),
|
|
||||||
0, 0,
|
|
||||||
h - p,
|
|
||||||
h - p,
|
|
||||||
iconFg);
|
|
||||||
|
|
||||||
// Module name
|
|
||||||
renderScope.drawText(
|
|
||||||
0.6f,
|
|
||||||
mod.getName(),
|
|
||||||
p + h + 4,
|
|
||||||
p + 1,
|
|
||||||
Theme.FONT.value,
|
|
||||||
fgColor);
|
|
||||||
|
|
||||||
// Version (right aligned)
|
|
||||||
String version = mod.getVersion();
|
|
||||||
int versionWidth = (int) (Fonts.getWidth(version, Theme.FONT.value) * 0.35f);
|
|
||||||
|
|
||||||
renderScope.drawText(
|
|
||||||
0.35f,
|
|
||||||
version,
|
|
||||||
width - p - versionWidth,
|
|
||||||
p + 1,
|
|
||||||
Theme.FONT.value,
|
|
||||||
fgColor);
|
|
||||||
|
|
||||||
// Tags
|
|
||||||
int xt = p + h + 4;
|
|
||||||
for (String tag : mod.getTags()) {
|
|
||||||
int tagWidth = (int) (Fonts.getWidth(tag, Theme.FONT.value) * 0.4f);
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(
|
|
||||||
xt,
|
|
||||||
p + (h / 2),
|
|
||||||
tagWidth + 6,
|
|
||||||
12,
|
|
||||||
5,
|
|
||||||
Theme.ACCENT.value);
|
|
||||||
|
|
||||||
renderScope.drawText(
|
|
||||||
0.4f,
|
|
||||||
tag,
|
|
||||||
xt + 2,
|
|
||||||
p + (h / 2) + 3,
|
|
||||||
Theme.FONT.value,
|
|
||||||
Theme.ACCENT_FG.value);
|
|
||||||
|
|
||||||
xt += tagWidth + 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Settings icon
|
|
||||||
renderScope.drawTexture(
|
|
||||||
Textures.SETTINGS,
|
|
||||||
iconX,
|
|
||||||
iconY,
|
|
||||||
0, 0,
|
|
||||||
s, s,
|
|
||||||
settingsColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
boolean settingsHover = Utils.isHovering(
|
|
||||||
mouseX - getSettingsX(),
|
|
||||||
mouseY - getSettingsY(),
|
|
||||||
getSettingsHitBox(),
|
|
||||||
getSettingsHitBox(),
|
|
||||||
1.0f);
|
|
||||||
|
|
||||||
if (settingsHover) {
|
|
||||||
MinecraftProvider.PROVIDER.setScreen(new ConfigEditor(mod.getConfig()));
|
|
||||||
} else {
|
|
||||||
mod.setEnabled(!mod.isEnabled());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getSettingsX() {
|
|
||||||
return width - s - p - expand;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getSettingsY() {
|
|
||||||
return height - s - p - expand;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getSettingsHitBox() {
|
|
||||||
return s + expand * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.Config;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.Utils;
|
|
||||||
import org.saturnclient.ui.resources.Textures;
|
|
||||||
import org.saturnclient.ui.screens.ConfigEditor;
|
|
||||||
import org.saturnclient.ui.screens.ModMenu;
|
|
||||||
import org.saturnclient.ui.screens.cosmetics.CloakMenu;
|
|
||||||
import org.saturnclient.ui.screens.store.CloakStore;
|
|
||||||
|
|
||||||
public class Sidebar extends Element {
|
|
||||||
public static class SidebarComponent {
|
|
||||||
Runnable onClick;
|
|
||||||
boolean end;
|
|
||||||
SaturnIdentifier sprite;
|
|
||||||
|
|
||||||
public SidebarComponent(SaturnIdentifier sprite, Runnable onClick, boolean end) {
|
|
||||||
this.onClick = onClick;
|
|
||||||
this.end = end;
|
|
||||||
this.sprite = sprite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable onClose;
|
|
||||||
SidebarComponent[] components = {
|
|
||||||
new Sidebar.SidebarComponent(Textures.MODS_TAB, () -> {
|
|
||||||
MinecraftProvider.PROVIDER.setScreen(new ModMenu());
|
|
||||||
}, false),
|
|
||||||
new Sidebar.SidebarComponent(Textures.SETTINGS, () -> {
|
|
||||||
MinecraftProvider.PROVIDER.setScreen(new ConfigEditor(Config.config));
|
|
||||||
}, false),
|
|
||||||
|
|
||||||
new Sidebar.SidebarComponent(Textures.SHIRT, () -> {
|
|
||||||
MinecraftProvider.PROVIDER.setScreen(new CloakMenu());
|
|
||||||
}, false),
|
|
||||||
|
|
||||||
new Sidebar.SidebarComponent(Textures.CLOSE, () -> {
|
|
||||||
onClose.run();
|
|
||||||
}, true),
|
|
||||||
|
|
||||||
new Sidebar.SidebarComponent(Textures.STORE, () -> {
|
|
||||||
MinecraftProvider.PROVIDER.setScreen(new CloakStore());
|
|
||||||
}, true),
|
|
||||||
};
|
|
||||||
int active = 0;
|
|
||||||
|
|
||||||
public Sidebar(int active, Runnable onClose) {
|
|
||||||
this.width = 30;
|
|
||||||
this.height = 350;
|
|
||||||
this.active = active;
|
|
||||||
this.onClose = onClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
int topRow = 0;
|
|
||||||
int bottomRow = 0;
|
|
||||||
|
|
||||||
int gap = 5; // 5px gap between icons
|
|
||||||
int padding = 10;
|
|
||||||
int sp = 30 - padding + gap;
|
|
||||||
int s = 30 - (padding * 2);
|
|
||||||
int s2 = s + padding;
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.BG_RADIUS.value, Theme.BACKGROUND.value);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (SidebarComponent component : components) {
|
|
||||||
int y = component.end ? ((height - (sp * bottomRow)) - (s * 2)) : (padding + (sp * topRow));
|
|
||||||
boolean selected = ctx.isHovering(0, y - (padding / 2), s2, s2) || active == i;
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(padding / 2, y - (padding / 2), s + padding,
|
|
||||||
s + padding, Theme.WIDGET_RADIUS.value, Theme.getBg(selected));
|
|
||||||
|
|
||||||
renderScope.drawTexture(component.sprite, padding, y, 0, 0, s, s, Theme.getFg(selected));
|
|
||||||
|
|
||||||
if (component.end) {
|
|
||||||
bottomRow += 1;
|
|
||||||
} else {
|
|
||||||
topRow += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int topRow = 0;
|
|
||||||
int bottomRow = 0;
|
|
||||||
|
|
||||||
int gap = 5;
|
|
||||||
int padding = 10;
|
|
||||||
int sp = 30 - padding + gap;
|
|
||||||
int s = 30 - (padding * 2);
|
|
||||||
int s2 = s + padding;
|
|
||||||
|
|
||||||
for (SidebarComponent component : components) {
|
|
||||||
int y = component.end ? ((height - (sp * bottomRow)) - (s * 2)) : (padding + (sp * topRow));
|
|
||||||
boolean hovering = Utils.isHovering(mouseX - (padding / 2), mouseY - (y - (padding / 2)), s2, s2, scale);
|
|
||||||
|
|
||||||
if (hovering) {
|
|
||||||
component.onClick.run();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (component.end) {
|
|
||||||
bottomRow += 1;
|
|
||||||
} else {
|
|
||||||
topRow += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class SkinPreview extends Element {
|
|
||||||
public static EntityDrawer DRAWER;
|
|
||||||
private boolean negativeAngle = false;
|
|
||||||
private float angle = 0.0f;
|
|
||||||
|
|
||||||
public SkinPreview(float angle, boolean negativeAngle) {
|
|
||||||
this.angle = angle;
|
|
||||||
this.negativeAngle = negativeAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
DRAWER.render(renderScope, negativeAngle, angle, scale, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface EntityDrawer {
|
|
||||||
public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale,
|
|
||||||
ElementContext ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.ConfigManager;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class FloatInput extends Input {
|
|
||||||
public Property<Float> prop;
|
|
||||||
|
|
||||||
public FloatInput(Property<Float> prop) {
|
|
||||||
this.width = 120;
|
|
||||||
this.height = Fonts.getHeight();
|
|
||||||
this.prop = prop;
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) {
|
|
||||||
if (text.equals("0") && cursorPosition == 1) {
|
|
||||||
text = "" + chr;
|
|
||||||
} else {
|
|
||||||
text = text.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
|
|
||||||
try {
|
|
||||||
prop.value = text.isEmpty() ? 0 : Float.parseFloat(text);
|
|
||||||
cursorPosition++;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void backspace() {
|
|
||||||
try {
|
|
||||||
if (text.length() == 0) {
|
|
||||||
text = "0";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
prop.value = Float.parseFloat(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkReset() {
|
|
||||||
if (prop.isReset) {
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
this.cursorPosition = 0;
|
|
||||||
prop.isReset = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class HexInput extends Element {
|
|
||||||
public Property<Integer> prop;
|
|
||||||
|
|
||||||
// Picker state
|
|
||||||
private boolean open = false;
|
|
||||||
private float hue = 0f;
|
|
||||||
private float opacity = 1f;
|
|
||||||
private int selectedX = 0;
|
|
||||||
private int selectedY = 0;
|
|
||||||
|
|
||||||
private boolean draggingOpacity = false;
|
|
||||||
|
|
||||||
// Dimensions
|
|
||||||
private static final int PICKER_WIDTH = 100;
|
|
||||||
private static final int PICKER_HEIGHT = 100;
|
|
||||||
private static final int SLIDER_WIDTH = 100;
|
|
||||||
private static final int SLIDER_HEIGHT = 10;
|
|
||||||
private static final int HUE_SLIDER_HEIGHT = 10;
|
|
||||||
|
|
||||||
public HexInput(Property<Integer> prop) {
|
|
||||||
this.prop = prop;
|
|
||||||
this.width = 58;
|
|
||||||
this.height = 20;
|
|
||||||
syncFromColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
open = !open;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
if (open) {
|
|
||||||
handlePickerClick(mouseX - width - 8, mouseY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
|
||||||
if (open) {
|
|
||||||
handlePickerDrag(mouseX - width - 8, mouseY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
|
||||||
draggingOpacity = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
// Draw the main color rectangle
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 6, prop.value);
|
|
||||||
|
|
||||||
if (!open)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Draw the picker relative to (width + 8, 0)
|
|
||||||
int pickerX = width + 8;
|
|
||||||
int pickerY = 0;
|
|
||||||
|
|
||||||
renderColorSquare(renderScope, pickerX, pickerY);
|
|
||||||
renderOpacitySlider(renderScope, pickerX, pickerY - SLIDER_HEIGHT - 10);
|
|
||||||
renderHueSlider(renderScope, pickerX, pickerY + PICKER_HEIGHT + 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderColorSquare(RenderScope renderScope, int xStart, int yStart) {
|
|
||||||
for (int x = 0; x < PICKER_WIDTH; x++) {
|
|
||||||
for (int y = 0; y < PICKER_HEIGHT; y++) {
|
|
||||||
float saturation = x / (float) PICKER_WIDTH;
|
|
||||||
float value = 1f - y / (float) PICKER_HEIGHT;
|
|
||||||
int color = Color.HSBtoRGB(hue, saturation, value);
|
|
||||||
int alpha = (int) (opacity * 255) & 0xFF;
|
|
||||||
color = (alpha << 24) | (color & 0xFFFFFF);
|
|
||||||
renderScope.fill(xStart + x, yStart + y, xStart + x + 1, yStart + y + 1, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw selection square
|
|
||||||
int selX = xStart + selectedX - 4;
|
|
||||||
int selY = yStart + selectedY - 4;
|
|
||||||
renderScope.fill(selX, selY, selX + 8, selY + 8, 0xFF000000 | prop.value);
|
|
||||||
renderScope.drawBorder(selX, selY, 8, 8, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderOpacitySlider(RenderScope renderScope, int xStart, int yStart) {
|
|
||||||
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
|
||||||
float localOpacity = x / (float) SLIDER_WIDTH;
|
|
||||||
int alpha = (int) (localOpacity * 255) & 0xFF;
|
|
||||||
int color = (alpha << 24) | (prop.value & 0xFFFFFF);
|
|
||||||
renderScope.fill(xStart + x, yStart, xStart + x + 1, yStart + SLIDER_HEIGHT, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
int knobX = xStart + (int) (opacity * SLIDER_WIDTH);
|
|
||||||
renderScope.fill(knobX - 1, yStart - 2, knobX + 1, yStart + SLIDER_HEIGHT + 2, 0xFF000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderHueSlider(RenderScope renderScope, int xStart, int yStart) {
|
|
||||||
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
|
||||||
float localHue = x / (float) SLIDER_WIDTH;
|
|
||||||
int color = Color.HSBtoRGB(localHue, 1f, 1f);
|
|
||||||
renderScope.fill(xStart + x, yStart, xStart + x + 1, yStart + HUE_SLIDER_HEIGHT, 0xFF000000 | color);
|
|
||||||
}
|
|
||||||
|
|
||||||
int knobX = xStart + (int) (hue * SLIDER_WIDTH);
|
|
||||||
renderScope.fill(knobX - 1, yStart - 2, knobX + 1, yStart + HUE_SLIDER_HEIGHT + 2, 0xFF000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePickerClick(double mouseX, double mouseY) {
|
|
||||||
// Color square
|
|
||||||
if (mouseX >= 0 && mouseX < PICKER_WIDTH && mouseY >= 0 && mouseY < PICKER_HEIGHT) {
|
|
||||||
selectedX = (int) mouseX;
|
|
||||||
selectedY = (int) mouseY;
|
|
||||||
updateColorFromSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Opacity slider
|
|
||||||
int opY = -SLIDER_HEIGHT - 10;
|
|
||||||
if (mouseX >= 0 && mouseX < SLIDER_WIDTH && mouseY >= opY && mouseY <= opY + SLIDER_HEIGHT) {
|
|
||||||
updateOpacity(mouseX);
|
|
||||||
draggingOpacity = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hue slider
|
|
||||||
int hueY = PICKER_HEIGHT + 10;
|
|
||||||
if (mouseX >= 0 && mouseX < SLIDER_WIDTH && mouseY >= hueY && mouseY <= hueY + HUE_SLIDER_HEIGHT) {
|
|
||||||
updateHue(mouseX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePickerDrag(double mouseX, double mouseY) {
|
|
||||||
// Opacity
|
|
||||||
if (draggingOpacity)
|
|
||||||
updateOpacity(mouseX);
|
|
||||||
|
|
||||||
// Color square
|
|
||||||
if (mouseX >= 0 && mouseX < PICKER_WIDTH && mouseY >= 0 && mouseY < PICKER_HEIGHT) {
|
|
||||||
selectedX = (int) mouseX;
|
|
||||||
selectedY = (int) mouseY;
|
|
||||||
updateColorFromSelection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateColorFromSelection() {
|
|
||||||
float saturation = selectedX / (float) PICKER_WIDTH;
|
|
||||||
float value = 1f - selectedY / (float) PICKER_HEIGHT;
|
|
||||||
int color = Color.HSBtoRGB(hue, saturation, value);
|
|
||||||
int alpha = (int) (opacity * 255) & 0xFF;
|
|
||||||
prop.value = (alpha << 24) | (color & 0xFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateHue(double mouseX) {
|
|
||||||
hue = (float) Math.max(0, Math.min(1, mouseX / SLIDER_WIDTH));
|
|
||||||
updateColorFromSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateOpacity(double mouseX) {
|
|
||||||
opacity = (float) Math.max(0, Math.min(1, mouseX / SLIDER_WIDTH));
|
|
||||||
updateColorFromSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void syncFromColor() {
|
|
||||||
int rgb = prop.value & 0xFFFFFF;
|
|
||||||
float[] hsb = Color.RGBtoHSB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF, null);
|
|
||||||
hue = hsb[0];
|
|
||||||
selectedX = (int) (hsb[1] * PICKER_WIDTH);
|
|
||||||
selectedY = (int) ((1f - hsb[2]) * PICKER_HEIGHT);
|
|
||||||
int alpha = (prop.value >> 24) & 0xFF;
|
|
||||||
if (alpha == 0)
|
|
||||||
alpha = 255;
|
|
||||||
opacity = alpha / 255f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.config.manager.Key;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public abstract class Input extends Element {
|
|
||||||
String text = "";
|
|
||||||
public int cursorPosition = 0;
|
|
||||||
|
|
||||||
public abstract void checkReset();
|
|
||||||
|
|
||||||
public abstract void backspace();
|
|
||||||
|
|
||||||
public boolean validateBackspace() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == Key.GLFW_KEY_BACKSPACE) {
|
|
||||||
if (cursorPosition > 0 && validateBackspace()) {
|
|
||||||
text = text.substring(0, cursorPosition - 1) +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
cursorPosition--;
|
|
||||||
backspace();
|
|
||||||
}
|
|
||||||
} else if (keyCode == Key.GLFW_KEY_LEFT) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
} else if (keyCode == Key.GLFW_KEY_RIGHT) {
|
|
||||||
if (cursorPosition < text.length()) {
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = text.substring(scrollOffset);
|
|
||||||
|
|
||||||
int newCursorPos = scrollOffset;
|
|
||||||
float textWidth = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < visibleText.length(); i++) {
|
|
||||||
textWidth = Fonts.getWidth(visibleText.substring(0, i + 1), Theme.FONT.value) * 0.6f;
|
|
||||||
|
|
||||||
if (textWidth > mouseX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCursorPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorPosition = newCursorPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
checkReset();
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
|
||||||
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = getVisibleText(scrollOffset);
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
renderScope.drawText(0.6f, visibleText, 4, 4, Theme.FONT.value, textColor);
|
|
||||||
|
|
||||||
if (focused) {
|
|
||||||
int cursorX = 4 +
|
|
||||||
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), Theme.FONT.value)
|
|
||||||
* 0.6f);
|
|
||||||
|
|
||||||
renderScope.drawRect(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getScrollOffset() {
|
|
||||||
if (text.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int maxWidth = width - 4; // Available width for text
|
|
||||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
|
||||||
String visibleText = text.substring(offset, cursorPosition);
|
|
||||||
if (Fonts.getWidth(visibleText, Theme.FONT.value) > maxWidth) {
|
|
||||||
offset++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getVisibleText(int scrollOffset) {
|
|
||||||
String visibleText = text.substring(scrollOffset);
|
|
||||||
|
|
||||||
// Ensure text does not overflow past the available width
|
|
||||||
for (int i = 1; i <= visibleText.length(); i++) {
|
|
||||||
if (Fonts.getWidth(visibleText.substring(0, i), Theme.FONT.value) > width - 4) {
|
|
||||||
return visibleText.substring(0, i - 1); // Trim overflow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visibleText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import org.saturnclient.config.manager.ConfigManager;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class IntInput extends Input {
|
|
||||||
public Property<Integer> prop;
|
|
||||||
|
|
||||||
public IntInput(Property<Integer> prop) {
|
|
||||||
this.width = 120;
|
|
||||||
this.height = Fonts.getHeight();
|
|
||||||
this.prop = prop;
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) {
|
|
||||||
if (text.equals("0") && cursorPosition == 1) {
|
|
||||||
text = "" + chr;
|
|
||||||
} else {
|
|
||||||
text = text.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
|
|
||||||
try {
|
|
||||||
prop.value = text.isEmpty() ? 0 : Integer.parseInt(text);
|
|
||||||
cursorPosition++;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void backspace() {
|
|
||||||
try {
|
|
||||||
if (text.length() == 0) {
|
|
||||||
text = "0";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
prop.value = Integer.parseInt(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkReset() {
|
|
||||||
if (prop.isReset) {
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
this.cursorPosition = 0;
|
|
||||||
prop.isReset = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.config.manager.Key;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class KeybindingSelector extends Element {
|
|
||||||
Property<Integer> prop;
|
|
||||||
|
|
||||||
public KeybindingSelector(Property<Integer> prop) {
|
|
||||||
this.prop = prop;
|
|
||||||
this.width = 120;
|
|
||||||
this.height = Fonts.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
|
||||||
String name = MinecraftProvider.PROVIDER.getKeyName(prop.value);
|
|
||||||
|
|
||||||
renderScope.drawText(0.6f,
|
|
||||||
prop.value == -1 ? "<NONE>"
|
|
||||||
: name != null ? name.toUpperCase() : "<Invalid-Key>",
|
|
||||||
4, 4, Theme.FONT.value, textColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == Key.GLFW_KEY_BACKSPACE) {
|
|
||||||
prop.value = -1;
|
|
||||||
} else {
|
|
||||||
prop.value = keyCode;
|
|
||||||
}
|
|
||||||
focused = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.Utils;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Select extends Element {
|
|
||||||
private Property<Integer> prop;
|
|
||||||
|
|
||||||
public Select(Property<Integer> prop) {
|
|
||||||
this.prop = prop;
|
|
||||||
this.width = 150;
|
|
||||||
this.height = 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawText(0.8f, "<", 0, 0, Theme.FONT.value, Theme.FOREGROUND.value);
|
|
||||||
|
|
||||||
String text = prop.getSelection();
|
|
||||||
|
|
||||||
renderScope.drawText(0.6f, text, (int) (width - ((float) Fonts.getWidth(text, Theme.FONT.value) * 0.6f)) / 2, 1,
|
|
||||||
Theme.FONT.value, Theme.FOREGROUND.value);
|
|
||||||
|
|
||||||
renderScope.drawText(0.8f, ">", width - 10, 0, Theme.FONT.value, Theme.FOREGROUND.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
if (Utils.isHovering(mouseX - (width - 10), mouseY, 10, height, 1.0f)) {
|
|
||||||
prop.next();
|
|
||||||
} else if (Utils.isHovering(mouseX, mouseY, 10, height, 1.0f)) {
|
|
||||||
prop.prev();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.saturnclient.ui.components.inputs;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class Toggle extends Element {
|
|
||||||
private Property<Boolean> prop;
|
|
||||||
|
|
||||||
public Toggle(Property<Boolean> prop) {
|
|
||||||
this.prop = prop;
|
|
||||||
this.width = 60;
|
|
||||||
this.height = 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, height,
|
|
||||||
Theme.withAlpha(0.5f, prop.value ? Theme.ACCENT.value : Theme.PRIMARY.value));
|
|
||||||
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30,
|
|
||||||
prop.value ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
prop.value = !prop.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.saturnclient.config.AnimationConfig;
|
|
||||||
import org.saturnclient.config.Config;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.ElementRenderer;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class AnimationStagger extends Element {
|
|
||||||
protected List<Element> children = new ArrayList<>();
|
|
||||||
public int delay;
|
|
||||||
|
|
||||||
public AnimationStagger(int delay) {
|
|
||||||
this.delay = delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnimationStagger(AnimationConfig config) {
|
|
||||||
this.delay = config.stagger.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Element element) {
|
|
||||||
if (!Config.stagger.value) {
|
|
||||||
element.animation = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.animation != null) {
|
|
||||||
element.animation.delay = delay * children.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.draw(children, element);
|
|
||||||
|
|
||||||
this.height = Math.max(this.height, element.y + element.height);
|
|
||||||
this.width = Math.max(this.width, element.x + element.width);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
ElementRenderer.INSTANCE.render(children, ctx.elapsed, renderScope,
|
|
||||||
ctx.mouseX,
|
|
||||||
ctx.mouseY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
ElementRenderer.INSTANCE.mouseClicked(children, mouseX, mouseY, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
ElementRenderer.INSTANCE.keyPressed(children, keyCode, scanCode, modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
|
||||||
ElementRenderer.INSTANCE.mouseDragged(children, mouseX, mouseY, button, deltaX, deltaY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
|
||||||
ElementRenderer.INSTANCE.mouseReleased(children, mouseX, mouseY, button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Button extends Element {
|
|
||||||
private String text;
|
|
||||||
private Runnable onClick;
|
|
||||||
|
|
||||||
public Button(String text, Runnable onClick) {
|
|
||||||
this.text = text;
|
|
||||||
this.onClick = onClick;
|
|
||||||
this.dimensions(Fonts.getWidth(text, Theme.FONT.value) + 50, 38);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
|
||||||
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
|
||||||
|
|
||||||
renderScope.drawText(text, Fonts.centerX(width, text, Theme.FONT.value), Fonts.centerY(height),
|
|
||||||
Theme.FONT.value,
|
|
||||||
ctx.isHovering() ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
if (onClick != null) {
|
|
||||||
onClick.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class ClickableTexture extends Element {
|
|
||||||
SaturnIdentifier sprite;
|
|
||||||
private Runnable onClick;
|
|
||||||
|
|
||||||
public ClickableTexture(SaturnIdentifier sprite, Runnable onClick) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
this.onClick = onClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height,
|
|
||||||
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
if (onClick != null) {
|
|
||||||
onClick.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.IMinecraftClient;
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.SvgTexture;
|
|
||||||
|
|
||||||
public class ImageTexture extends Element {
|
|
||||||
SaturnIdentifier sprite;
|
|
||||||
|
|
||||||
public ImageTexture(SaturnIdentifier sprite) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
if (sprite.toString().endsWith(".svg")) {
|
|
||||||
IMinecraftClient client = MinecraftProvider.PROVIDER.getClient();
|
|
||||||
|
|
||||||
int renderWidth = (int) (width * client.getWindow().getFramebufferWidth() / client.getWindow().getWidth());
|
|
||||||
int renderHeight = (int) (height * client.getWindow().getFramebufferHeight()
|
|
||||||
/ client.getWindow().getHeight());
|
|
||||||
|
|
||||||
SaturnIdentifier pngId = SvgTexture.getSvg(client, sprite, renderWidth * 2, renderHeight * 2);
|
|
||||||
|
|
||||||
this.sprite = pngId;
|
|
||||||
if (pngId == null) {
|
|
||||||
System.err.println("Failed to render SVG: " + sprite);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.drawTexture(this.sprite, 0, 0, 0, 0, width, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.anim.SlideX;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
import org.saturnclient.ui.resources.Textures;
|
|
||||||
|
|
||||||
public class Notification extends Element {
|
|
||||||
private static Property<Integer> error = Property.color(0xFFbf212f);
|
|
||||||
private static Property<Integer> info = Property.color(0xFF264b96);
|
|
||||||
private static Property<Integer> success = Property.color(0xFF27b376);
|
|
||||||
|
|
||||||
public static enum NotificationKind {
|
|
||||||
Error,
|
|
||||||
Info,
|
|
||||||
Success,
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationKind kind;
|
|
||||||
String text;
|
|
||||||
String title;
|
|
||||||
|
|
||||||
public Notification(int width, int height, NotificationKind kind, String title, String text) {
|
|
||||||
this.kind = kind;
|
|
||||||
this.text = text;
|
|
||||||
this.title = title;
|
|
||||||
this.width = (int) Math.max(Fonts.getWidth(text, 1) * 0.6f, Fonts.getWidth(title, 1)) + 20;
|
|
||||||
this.height = 50;
|
|
||||||
this.x = width - this.width - 15;
|
|
||||||
this.y = height - this.height - 15;
|
|
||||||
this.animation = new SlideX(700, -width);
|
|
||||||
this.duration = 3000;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, Theme.PRIMARY.value);
|
|
||||||
switch (kind) {
|
|
||||||
case Error:
|
|
||||||
renderScope.drawTexture(Textures.CIRCLE_X, 9, 9, 0, 0, 15, 15, error.value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Info:
|
|
||||||
renderScope.drawTexture(Textures.INFO, 9, 9, 0, 0, 15, 15, info.value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Success:
|
|
||||||
renderScope.drawTexture(Textures.CHECK, 9, 9, 0, 0, 15, 15, success.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
renderScope.drawText(0.7f, title, 32, 10, 1, -1);
|
|
||||||
renderScope.drawText(0.5f, text, 32, 28, 1, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.config.manager.Property;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.ElementRenderer;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class Scroll extends Element {
|
|
||||||
private static Property<Integer> scrollBarRadius = Property.integer(10);
|
|
||||||
private static Property<Integer> scrollBarWidth = Property.integer(5);
|
|
||||||
private static Property<Integer> scrollBarPadding = Property.integer(5);
|
|
||||||
|
|
||||||
int padding = 0;
|
|
||||||
|
|
||||||
protected List<Element> children = new ArrayList<>();
|
|
||||||
int scroll = 0;
|
|
||||||
int maxScroll = 0;
|
|
||||||
|
|
||||||
public Scroll(int padding) {
|
|
||||||
this.padding = padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Element element) {
|
|
||||||
ElementRenderer.INSTANCE.draw(children, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
calculateMaxScroll();
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height,
|
|
||||||
Theme.BG_RADIUS.value, Theme.BACKGROUND.value);
|
|
||||||
|
|
||||||
renderScope.enableScissor(padding, padding, width - padding, height - padding);
|
|
||||||
renderScope.getMatrixStack().push();
|
|
||||||
renderScope.getMatrixStack().translate(padding, -scroll + padding, 0);
|
|
||||||
|
|
||||||
ElementRenderer.INSTANCE.render(children, ctx.elapsed, renderScope,
|
|
||||||
ctx.mouseX - padding,
|
|
||||||
ctx.mouseY - padding + scroll);
|
|
||||||
|
|
||||||
renderScope.getMatrixStack().pop();
|
|
||||||
renderScope.disableScissor();
|
|
||||||
|
|
||||||
if (maxScroll > 0) {
|
|
||||||
renderScope.drawRoundedRectangle(
|
|
||||||
width - scrollBarWidth.value - scrollBarPadding.value,
|
|
||||||
calculateScrollBarY(),
|
|
||||||
scrollBarWidth.value,
|
|
||||||
calculateScrollBarHeight(),
|
|
||||||
scrollBarRadius.value,
|
|
||||||
Theme.SCROLL.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) {
|
|
||||||
scroll -= verticalAmount;
|
|
||||||
if (scroll < 0) {
|
|
||||||
scroll = 0;
|
|
||||||
} else if (scroll > maxScroll) {
|
|
||||||
scroll = maxScroll;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Element dimensions(int width, int height) {
|
|
||||||
super.dimensions(width, height);
|
|
||||||
|
|
||||||
maxScroll = 0;
|
|
||||||
for (Element element : children) {
|
|
||||||
maxScroll = Math.max(maxScroll, (element.y + element.height + padding) - (height - padding * 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int calculateScrollBarHeight() {
|
|
||||||
if (maxScroll <= 0)
|
|
||||||
return height - (scrollBarPadding.value * 2);
|
|
||||||
return Math.max(20, (height * height) / (height + maxScroll + 10)) - (scrollBarPadding.value * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int calculateScrollBarY() {
|
|
||||||
int scrollBarHeight = calculateScrollBarHeight();
|
|
||||||
if (maxScroll <= 0)
|
|
||||||
return scrollBarPadding.value;
|
|
||||||
int y = (scroll * (height - scrollBarHeight - scrollBarPadding.value * 2)) / maxScroll + scrollBarPadding.value;
|
|
||||||
return Math.min(y, height - scrollBarHeight - scrollBarPadding.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calculateMaxScroll() {
|
|
||||||
maxScroll = 0;
|
|
||||||
|
|
||||||
for (Element element : children) {
|
|
||||||
int bottom = element.y + element.height;
|
|
||||||
maxScroll = Math.max(maxScroll, bottom - height + padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxScroll > 0) {
|
|
||||||
maxScroll = maxScroll + 10;
|
|
||||||
} else {
|
|
||||||
maxScroll = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
ElementRenderer.INSTANCE.keyPressed(children, keyCode, scanCode, modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
ElementRenderer.INSTANCE.mouseClicked(children, mouseX - padding, mouseY - padding + scroll, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
|
||||||
ElementRenderer.INSTANCE.mouseDragged(children, mouseX - padding, mouseY - padding + scroll, button, deltaX,
|
|
||||||
deltaY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(double mouseX, double mouseY, int button) {
|
|
||||||
ElementRenderer.INSTANCE.mouseReleased(children, mouseX - padding, mouseY - padding + scroll, button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.Utils;
|
|
||||||
|
|
||||||
public class TabMenu extends Element {
|
|
||||||
public static class TabMenuComponent {
|
|
||||||
Runnable onClick;
|
|
||||||
SaturnIdentifier sprite;
|
|
||||||
|
|
||||||
public TabMenuComponent(SaturnIdentifier sprite, Runnable onClick) {
|
|
||||||
this.onClick = onClick;
|
|
||||||
this.sprite = sprite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TabMenuComponent[] components;
|
|
||||||
public int selectedScreen = 0;
|
|
||||||
|
|
||||||
public TabMenu(int active, TabMenuComponent... components) {
|
|
||||||
this.components = components;
|
|
||||||
width = 25 * components.length + 6;
|
|
||||||
height = 30;
|
|
||||||
this.selectedScreen = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, Theme.PRIMARY.value);
|
|
||||||
|
|
||||||
int col = 0;
|
|
||||||
for (TabMenuComponent component : components) {
|
|
||||||
int x = 25 * col + 5;
|
|
||||||
|
|
||||||
boolean hovering = ctx.isHovering(x, 5, 20, 20) || selectedScreen == col;
|
|
||||||
|
|
||||||
if (hovering) {
|
|
||||||
renderScope.drawRoundedRectangle(x, 5, 20, 20, Theme.WIDGET_RADIUS.value, Theme.ACCENT.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10,
|
|
||||||
hovering ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
|
||||||
|
|
||||||
col++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int col = 0;
|
|
||||||
for (TabMenuComponent component : components) {
|
|
||||||
int x = 25 * col + 5;
|
|
||||||
if (Utils.isHovering(mouseX - x, mouseY - 5, 20, 20, 1.0f)) {
|
|
||||||
component.onClick.run();
|
|
||||||
}
|
|
||||||
col++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
import org.saturnclient.ui.resources.Fonts;
|
|
||||||
|
|
||||||
public class Text extends Element {
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
public Text(String text) {
|
|
||||||
this.text = text;
|
|
||||||
width = Fonts.getWidth(text, Theme.FONT.value);
|
|
||||||
height = Fonts.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawText(this.text, 0, 0, Theme.FONT.value, Theme.FOREGROUND.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package org.saturnclient.ui.elements;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
import org.saturnclient.config.Theme;
|
|
||||||
import org.saturnclient.ui.Element;
|
|
||||||
import org.saturnclient.ui.ElementContext;
|
|
||||||
import org.saturnclient.ui.RenderScope;
|
|
||||||
|
|
||||||
public class TextureButton extends Element {
|
|
||||||
SaturnIdentifier sprite;
|
|
||||||
private Runnable onClick;
|
|
||||||
static int padding = 14;
|
|
||||||
|
|
||||||
public TextureButton(SaturnIdentifier sprite, Runnable onClick) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
this.onClick = onClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
|
||||||
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
|
||||||
|
|
||||||
int texWidth = width - padding;
|
|
||||||
int texHeight = height - padding;
|
|
||||||
|
|
||||||
renderScope.drawTexture(sprite, padding / 2, padding / 2, 0, 0, texWidth, texHeight,
|
|
||||||
ctx.isHovering() ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
if (onClick != null) {
|
|
||||||
onClick.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package org.saturnclient.ui.resources;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
|
|
||||||
public class Fonts {
|
|
||||||
public static final SaturnIdentifier INTER = SaturnIdentifier.of("saturnclient", "inter");
|
|
||||||
public static final SaturnIdentifier INTER_BOLD = SaturnIdentifier.of("saturnclient", "inter_bold");
|
|
||||||
public static final SaturnIdentifier DEFAULT = SaturnIdentifier.ofVanilla("default");
|
|
||||||
|
|
||||||
public static SaturnIdentifier getFont(int font) {
|
|
||||||
switch (font) {
|
|
||||||
case 0:
|
|
||||||
return DEFAULT;
|
|
||||||
case 1:
|
|
||||||
return INTER;
|
|
||||||
default:
|
|
||||||
return INTER_BOLD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getWidth(String text, int font) {
|
|
||||||
int w = 0;
|
|
||||||
for (String line : text.split("\n")) {
|
|
||||||
w = Math.max(w, MinecraftProvider.PROVIDER.getWidth(line, font));
|
|
||||||
}
|
|
||||||
if (font == 0) {
|
|
||||||
return w * 2;
|
|
||||||
} else {
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getHeight() {
|
|
||||||
return 18;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int centerX(int w, String text, int font) {
|
|
||||||
return (w - Fonts.getWidth(text, font)) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int centerY(int h) {
|
|
||||||
return (h - 18) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package org.saturnclient.ui.resources;
|
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.kitfox.svg.SVGDiagram;
|
|
||||||
import com.kitfox.svg.SVGUniverse;
|
|
||||||
|
|
||||||
import org.saturnclient.common.minecraft.IMinecraftClient;
|
|
||||||
import org.saturnclient.common.minecraft.MinecraftProvider;
|
|
||||||
import org.saturnclient.common.minecraft.bindings.SaturnIdentifier;
|
|
||||||
|
|
||||||
public class SvgTexture {
|
|
||||||
|
|
||||||
private static List<SaturnIdentifier> svgCache = new ArrayList<>();
|
|
||||||
|
|
||||||
private static BufferedImage renderSvg(InputStream svgStream, int width, int height) throws Exception {
|
|
||||||
// Load SVG
|
|
||||||
SVGUniverse universe = new SVGUniverse();
|
|
||||||
java.net.URI uri = universe.loadSVG(svgStream, "tempSvg");
|
|
||||||
SVGDiagram diagram = universe.getDiagram(uri);
|
|
||||||
|
|
||||||
// Get intrinsic size of SVG
|
|
||||||
float svgWidth = (float) diagram.getWidth();
|
|
||||||
float svgHeight = (float) diagram.getHeight();
|
|
||||||
|
|
||||||
// Compute scale factors
|
|
||||||
float scaleX = width / svgWidth;
|
|
||||||
float scaleY = height / svgHeight;
|
|
||||||
|
|
||||||
// Create output image
|
|
||||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D g = image.createGraphics();
|
|
||||||
|
|
||||||
// Enable anti-aliasing for smooth scaling
|
|
||||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
|
||||||
|
|
||||||
// Apply scaling transform
|
|
||||||
g.scale(scaleX, scaleY);
|
|
||||||
|
|
||||||
// Render SVG
|
|
||||||
diagram.render(g);
|
|
||||||
|
|
||||||
g.dispose();
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnIdentifier getSvg(IMinecraftClient client, SaturnIdentifier svgImage, int width, int height) {
|
|
||||||
SaturnIdentifier id = SaturnIdentifier
|
|
||||||
.of(svgImage.toString().replaceAll("\\.svg$", (width + "_" + height).toString() + ".png"));
|
|
||||||
|
|
||||||
if (svgCache.contains(id)) {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
try (InputStream svgStream = client.getResource(svgImage)) {
|
|
||||||
|
|
||||||
BufferedImage image = renderSvg(svgStream, width, height);
|
|
||||||
|
|
||||||
MinecraftProvider.PROVIDER.registerBufferedImageTexture(id, image);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user