mirror of
https://github.com/Miasmusa/Shadow.git
synced 2024-11-14 19:04:54 -05:00
proto admin dashboard now has the ability to delete accounts + reformat
This commit is contained in:
parent
a561a8025d
commit
7e99e9f9d6
7 changed files with 192 additions and 121 deletions
|
@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets;
|
|||
|
||||
public class OnlineAPI extends Command {
|
||||
static final File SESSION_KEY_FILE = new File(ShadowMain.BASE, "session.sip");
|
||||
|
||||
public OnlineAPI() {
|
||||
super("OnlineAPI", "Manage your API connection to the mothership", "onlineapi", "shadowapi", "onlineservices");
|
||||
tryToRecoverSession();
|
||||
|
@ -37,6 +38,7 @@ public class OnlineAPI extends Command {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
void tryToRecoverSession() {
|
||||
if (SESSION_KEY_FILE.exists()) {
|
||||
try {
|
||||
|
@ -54,6 +56,7 @@ public class OnlineAPI extends Command {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PossibleArgument getSuggestionsWithType(int index, String[] args) {
|
||||
if (index == 0) return new PossibleArgument(ArgumentType.STRING, "login", "logout");
|
||||
|
|
|
@ -18,6 +18,7 @@ public class Test extends Command {
|
|||
@Override
|
||||
public void onExecute(String[] args) {
|
||||
if (ShadowAPIWrapper.getAuthKey() != null && ShadowAPIWrapper.isCurrentUserAdmin()) {
|
||||
System.out.println(ShadowAPIWrapper.getAccounts());
|
||||
Utils.TickManager.runInNTicks(5, () -> {
|
||||
ShadowMain.client.setScreen(new OnlineServicesDashboardScreen());
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package net.shadow.client.feature.gui.screen;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.gui.Element;
|
||||
|
@ -16,6 +17,7 @@ import net.shadow.client.feature.gui.widget.RoundButton;
|
|||
import net.shadow.client.helper.IRCWebSocket;
|
||||
import net.shadow.client.helper.ShadowAPIWrapper;
|
||||
import net.shadow.client.helper.font.FontRenderers;
|
||||
import net.shadow.client.helper.font.adapter.impl.BruhAdapter;
|
||||
import net.shadow.client.helper.render.ClipStack;
|
||||
import net.shadow.client.helper.render.Rectangle;
|
||||
import net.shadow.client.helper.render.Renderer;
|
||||
|
@ -33,7 +35,11 @@ import java.util.Objects;
|
|||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class OnlineServicesDashboardScreen extends ClientScreen implements FastTickable {
|
||||
static List<LogsFieldWidget.LogEntry> logs = new CopyOnWriteArrayList<>();
|
||||
long reconnectTime = System.currentTimeMillis();
|
||||
SimpleWebsocket logsSocket;
|
||||
AccountList dvw;
|
||||
|
||||
void initSocket() {
|
||||
if (ShadowAPIWrapper.getAuthKey() != null) {
|
||||
logs.clear();
|
||||
|
@ -44,6 +50,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT
|
|||
logsSocket.connect();
|
||||
}
|
||||
}
|
||||
|
||||
void socketMessageRecieved(String msg) {
|
||||
IRCWebSocket.Packet pack = new Gson().fromJson(msg, IRCWebSocket.Packet.class);
|
||||
if (pack.id.equals("log")) {
|
||||
|
@ -51,20 +58,24 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT
|
|||
logs.add(0, new LogsFieldWidget.LogEntry(Map.of("Time", sdf.format(pack.data.get("time")), "Severity", pack.data.get("severity").toString()), pack.data.get("message").toString()));
|
||||
}
|
||||
}
|
||||
static List<LogsFieldWidget.LogEntry> logs = new CopyOnWriteArrayList<>();
|
||||
SimpleWebsocket logsSocket;
|
||||
|
||||
void populateAccountList() {
|
||||
dvw.aww.clear();
|
||||
double yO = 0;
|
||||
for (ShadowAPIWrapper.AccountEntry account : ShadowAPIWrapper.getAccounts()) {
|
||||
AccountViewerWidget avw = new AccountViewerWidget(account.username, account.password, 0, yO, 300, 30, () -> {
|
||||
if (ShadowAPIWrapper.deleteAccount(account.username, account.password)) this.populateAccountList();
|
||||
});
|
||||
yO += avw.height + 5;
|
||||
dvw.add(avw);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
addDrawableChild(new LogsFieldWidget(5, 5, width - 10, height / 2d - 5, OnlineServicesDashboardScreen.logs));
|
||||
AccountList dvw = new AccountList(5,height/2d+5,300,height/2d-10);
|
||||
double yOff = 0;
|
||||
for(int i = 0;i<20;i++) {
|
||||
AccountViewerWidget avw = new AccountViewerWidget("Among","us "+i,0,yOff,300,30,() -> {
|
||||
System.out.println("deleted");
|
||||
});
|
||||
dvw.add(avw);
|
||||
yOff += avw.height+5;
|
||||
}
|
||||
dvw = new AccountList(5, height / 2d + 5, 300, height / 2d - 10);
|
||||
populateAccountList();
|
||||
addDrawableChild(dvw);
|
||||
}
|
||||
|
||||
|
@ -89,6 +100,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT
|
|||
}
|
||||
return super.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
static
|
||||
class AccountViewerWidget implements Element, Drawable, Selectable, FastTickable {
|
||||
|
@ -96,9 +108,11 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT
|
|||
final double x, y, width, height;
|
||||
final Runnable onDelete;
|
||||
RoundButton deleteBtn = null;
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
if (deleteBtn == null) deleteBtn = new RoundButton(RoundButton.STANDARD,x+width-(height-FontRenderers.getRenderer().getFontHeight())/2d-60,y+(height-20)/2d,60,20,"Delete",onDelete);
|
||||
if (deleteBtn == null)
|
||||
deleteBtn = new RoundButton(RoundButton.STANDARD, x + width - (height - 20) / 2d - 60, y + (height - 20) / 2d, 60, 20, "Delete", onDelete);
|
||||
Renderer.R2D.renderRoundedQuad(matrices, new Color(10, 10, 20), x, y, x + width, y + height, 5, 20);
|
||||
double h = FontRenderers.getRenderer().getFontHeight();
|
||||
double pad = height - h;
|
||||
|
@ -127,38 +141,30 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT
|
|||
return deleteBtn.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
class LogsFieldWidget implements Element, Drawable, Selectable, FastTickable {
|
||||
public record LogEntry(Map<String, String> additionalProps, String msg) {
|
||||
|
||||
}
|
||||
record Bruh(String content, double width) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Bruh bruh = (Bruh) o;
|
||||
return Objects.equals(content, bruh.content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(content, width);
|
||||
}
|
||||
}
|
||||
final double x, y, w, h;
|
||||
final List<LogEntry> logs;
|
||||
Scroller scroller = new Scroller(0);
|
||||
|
||||
double heightPerLine() {
|
||||
return FontRenderers.getRenderer().getFontHeight() + 8;
|
||||
}
|
||||
|
||||
double contentHeight() {
|
||||
return heightPerLine() + logs.size() * heightPerLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
double yOffset = heightPerLine();
|
||||
Renderer.R2D.renderRoundedQuad(matrices, new Color(10, 10, 20), x, y, x + w, y + h, 5, 20);
|
||||
if (logs.isEmpty()) {
|
||||
BruhAdapter ba = FontRenderers.getCustomSize(40);
|
||||
ba.drawCenteredString(matrices, "No logs yet", x + w / 2d, y + h / 2d - ba.getFontHeight() / 2d, 1f, 1f, 1f, 0.3f);
|
||||
return;
|
||||
}
|
||||
List<Bruh> bruhs = new ArrayList<>();
|
||||
for (LogEntry log : logs) {
|
||||
log.additionalProps.forEach((s, s2) -> {
|
||||
|
@ -224,15 +230,38 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT
|
|||
}
|
||||
return Element.super.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
|
||||
public record LogEntry(Map<String, String> additionalProps, String msg) {
|
||||
|
||||
}
|
||||
|
||||
record Bruh(String content, double width) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Bruh bruh = (Bruh) o;
|
||||
return Objects.equals(content, bruh.content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(content, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
class AccountList implements Element, Drawable, Selectable, FastTickable {
|
||||
final double x, y, w, h;
|
||||
@Getter
|
||||
List<AccountViewerWidget> aww = new ArrayList<>();
|
||||
Scroller s = new Scroller(0);
|
||||
final double x, y, w, h;
|
||||
|
||||
public void add(AccountViewerWidget v) {
|
||||
aww.add(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
matrices.push();
|
||||
|
|
|
@ -20,9 +20,11 @@ import java.net.URI;
|
|||
public class IRC extends Module {
|
||||
static String ircPrefix = "#";
|
||||
IRCWebSocket wsS;
|
||||
|
||||
public IRC() {
|
||||
super("IRC", "Chat with others using the client", ModuleType.MISC);
|
||||
}
|
||||
|
||||
@EventListener(type = EventType.PACKET_SEND)
|
||||
void onPackSent(PacketEvent pe) {
|
||||
if (pe.getPacket() instanceof ChatMessageC2SPacket msg) {
|
||||
|
|
|
@ -17,24 +17,6 @@ import java.net.URI;
|
|||
import java.util.Map;
|
||||
|
||||
public class IRCWebSocket extends WebSocketClient {
|
||||
@AllArgsConstructor
|
||||
public static
|
||||
class Packet {
|
||||
public String id;
|
||||
public Map<String, Object> data;
|
||||
|
||||
public String toRawPacket() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Packet{" +
|
||||
"id='" + id + '\'' +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
String authToken;
|
||||
Runnable onClose;
|
||||
public IRCWebSocket(URI serverUri, String authToken, Runnable onClose) {
|
||||
|
@ -82,4 +64,23 @@ public class IRCWebSocket extends WebSocketClient {
|
|||
public void onError(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static
|
||||
class Packet {
|
||||
public String id;
|
||||
public Map<String, Object> data;
|
||||
|
||||
public String toRawPacket() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Packet{" +
|
||||
"id='" + id + '\'' +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ import java.net.http.HttpClient;
|
|||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ShadowAPIWrapper {
|
||||
|
@ -37,6 +39,7 @@ public class ShadowAPIWrapper {
|
|||
static HttpResponse<String> get(String path) {
|
||||
return request(path, "GET", HttpRequest.BodyPublishers.noBody());
|
||||
}
|
||||
|
||||
static HttpResponse<String> request(String path, String method, HttpRequest.BodyPublisher publisher) {
|
||||
URI u = URI.create(BASE_URL + path);
|
||||
HttpRequest request = HttpRequest.newBuilder().method(method, publisher).uri(u).header("Authorization", authKey).build();
|
||||
|
@ -47,12 +50,15 @@ public class ShadowAPIWrapper {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static HttpResponse<String> post(String path, String data) {
|
||||
return request(path, "POST", HttpRequest.BodyPublishers.ofString(data));
|
||||
}
|
||||
|
||||
public static void logout() {
|
||||
authKey = "";
|
||||
}
|
||||
|
||||
public static boolean loginWithKey(String session) {
|
||||
String prevAuthKey = authKey;
|
||||
authKey = session;
|
||||
|
@ -65,6 +71,7 @@ public class ShadowAPIWrapper {
|
|||
currentUserIsAdmin = (boolean) info.getOrDefault("isAdmin", false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean attemptLogin(String username, String password) {
|
||||
String d = gson.toJson(Map.of(
|
||||
"username", username,
|
||||
|
@ -76,6 +83,20 @@ public class ShadowAPIWrapper {
|
|||
if (uResp.statusCode() != 200) return false;
|
||||
return loginWithKey(uResp.body());
|
||||
}
|
||||
|
||||
public static List<AccountEntry> getAccounts() {
|
||||
HttpResponse<String> a = get("/users/admin/list");
|
||||
if (a.statusCode() != 200) return List.of();
|
||||
return new ArrayList<>(List.of(new Gson().fromJson(a.body(), AccountEntry[].class)));
|
||||
}
|
||||
|
||||
public static boolean deleteAccount(String user, String pass) {
|
||||
HttpResponse<String> s = request("/users/admin/delete", "DELETE", HttpRequest.BodyPublishers.ofString(new Gson().toJson(
|
||||
Map.of("username", user, "password", pass)
|
||||
)));
|
||||
return s != null && s.statusCode() == 200;
|
||||
}
|
||||
|
||||
public static boolean putItem(ItemStack stack) {
|
||||
HttpResponse<String> a = request("/items", "PUT", HttpRequest.BodyPublishers.ofString(gson.toJson(Map.of(
|
||||
"itemName", Registry.ITEM.getId(stack.getItem()).getPath(),
|
||||
|
@ -85,4 +106,17 @@ public class ShadowAPIWrapper {
|
|||
System.out.println(a.body());
|
||||
return a.statusCode() == 200;
|
||||
}
|
||||
|
||||
public static class AccountEntry {
|
||||
public String username, password, apiKey;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AccountEntry{" +
|
||||
"username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", apiKey='" + apiKey + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.function.Consumer;
|
|||
public class SimpleWebsocket extends WebSocketClient {
|
||||
Runnable onClose;
|
||||
Consumer<String> onMessage;
|
||||
|
||||
public SimpleWebsocket(URI serverUri, Map<String, String> headers, Runnable c, Consumer<String> msg) {
|
||||
super(serverUri, headers);
|
||||
this.onClose = c;
|
||||
|
|
Loading…
Reference in a new issue