From 7e99e9f9d648ea5e75d04ff06e8abb3eeb16a6e2 Mon Sep 17 00:00:00 2001 From: 0x3C50 Date: Thu, 28 Apr 2022 05:39:31 +0200 Subject: [PATCH] proto admin dashboard now has the ability to delete accounts + reformat --- .../feature/command/impl/OnlineAPI.java | 15 +- .../client/feature/command/impl/Test.java | 1 + .../screen/OnlineServicesDashboardScreen.java | 149 +++++++++++------- .../client/feature/module/impl/misc/IRC.java | 6 +- .../shadow/client/helper/IRCWebSocket.java | 95 +++++------ .../client/helper/ShadowAPIWrapper.java | 46 +++++- .../client/helper/ws/SimpleWebsocket.java | 1 + 7 files changed, 192 insertions(+), 121 deletions(-) diff --git a/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java b/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java index 9e9e99a..240eeac 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java +++ b/src/main/java/net/shadow/client/feature/command/impl/OnlineAPI.java @@ -22,14 +22,15 @@ 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"); + super("OnlineAPI", "Manage your API connection to the mothership", "onlineapi", "shadowapi", "onlineservices"); tryToRecoverSession(); Events.registerEventHandler(EventType.CONFIG_SAVE, event -> { String authKey = ShadowAPIWrapper.getAuthKey(); if (authKey != null) { try { - FileUtils.write(SESSION_KEY_FILE,authKey,StandardCharsets.UTF_8); + FileUtils.write(SESSION_KEY_FILE, authKey, StandardCharsets.UTF_8); } catch (Exception e) { System.out.println("failed to save session :("); e.printStackTrace(); @@ -37,6 +38,7 @@ public class OnlineAPI extends Command { } }); } + void tryToRecoverSession() { if (SESSION_KEY_FILE.exists()) { try { @@ -54,19 +56,20 @@ public class OnlineAPI extends Command { } } } + @Override public PossibleArgument getSuggestionsWithType(int index, String[] args) { if (index == 0) return new PossibleArgument(ArgumentType.STRING, "login", "logout"); if (args[0].equalsIgnoreCase("login")) { - return StaticArgumentServer.serveFromStatic(index-1,new PossibleArgument(ArgumentType.STRING, "(username)"), new PossibleArgument(ArgumentType.STRING, "(password)")); + return StaticArgumentServer.serveFromStatic(index - 1, new PossibleArgument(ArgumentType.STRING, "(username)"), new PossibleArgument(ArgumentType.STRING, "(password)")); } return super.getSuggestionsWithType(index, args); } @Override public void onExecute(String[] args) throws CommandException { - validateArgumentsLength(args,1, "Need an action"); - switch(args[0].toLowerCase()) { + validateArgumentsLength(args, 1, "Need an action"); + switch (args[0].toLowerCase()) { case "login" -> { if (ShadowAPIWrapper.getAuthKey() != null) { error("You're already logged in!"); @@ -74,7 +77,7 @@ public class OnlineAPI extends Command { } validateArgumentsLength(args, 3, "Need action, username and password"); if (ShadowAPIWrapper.attemptLogin(args[1], args[2])) { - success("You're now logged in as "+args[1]+". Try using IRC or the item market ;)"); + success("You're now logged in as " + args[1] + ". Try using IRC or the item market ;)"); } else { error("Failed to login. Check if username and password are correct"); } diff --git a/src/main/java/net/shadow/client/feature/command/impl/Test.java b/src/main/java/net/shadow/client/feature/command/impl/Test.java index c4a0128..93e0b05 100644 --- a/src/main/java/net/shadow/client/feature/command/impl/Test.java +++ b/src/main/java/net/shadow/client/feature/command/impl/Test.java @@ -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()); }); diff --git a/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java b/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java index 8815c59..ecefc23 100644 --- a/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java +++ b/src/main/java/net/shadow/client/feature/gui/screen/OnlineServicesDashboardScreen.java @@ -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,17 +35,22 @@ import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; public class OnlineServicesDashboardScreen extends ClientScreen implements FastTickable { + static List logs = new CopyOnWriteArrayList<>(); long reconnectTime = System.currentTimeMillis(); + SimpleWebsocket logsSocket; + AccountList dvw; + void initSocket() { if (ShadowAPIWrapper.getAuthKey() != null) { logs.clear(); - logsSocket = new SimpleWebsocket(URI.create(ShadowAPIWrapper.BASE_WS+"/admin/logs"), Map.of("Authorization", ShadowAPIWrapper.getAuthKey()), () -> { - reconnectTime = System.currentTimeMillis()+ Duration.ofSeconds(3).toMillis(); + logsSocket = new SimpleWebsocket(URI.create(ShadowAPIWrapper.BASE_WS + "/admin/logs"), Map.of("Authorization", ShadowAPIWrapper.getAuthKey()), () -> { + reconnectTime = System.currentTimeMillis() + Duration.ofSeconds(3).toMillis(); logs.clear(); }, this::socketMessageRecieved); 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 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; - } + addDrawableChild(new LogsFieldWidget(5, 5, width - 10, height / 2d - 5, OnlineServicesDashboardScreen.logs)); + 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,14 +108,16 @@ 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); - Renderer.R2D.renderRoundedQuad(matrices,new Color(10,10,20),x,y,x+width,y+height,5,20); + 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; + double pad = height - h; - FontRenderers.getRenderer().drawString(matrices,username+":"+password,x+pad/2d,y+height/2d-h/2d,0xFFFFFF); + FontRenderers.getRenderer().drawString(matrices, username + ":" + password, x + pad / 2d, y + height / 2d - h / 2d, 0xFFFFFF); deleteBtn.render(matrices, mouseX, mouseY, delta); } @@ -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 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 logs; Scroller scroller = new Scroller(0); + double heightPerLine() { - return FontRenderers.getRenderer().getFontHeight()+8; + return FontRenderers.getRenderer().getFontHeight() + 8; } + double contentHeight() { - return heightPerLine()+logs.size()*heightPerLine(); + 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); + 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 bruhs = new ArrayList<>(); for (LogEntry log : logs) { log.additionalProps.forEach((s, s2) -> { @@ -174,25 +180,25 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT } double xOffset = 4; for (Bruh bruh : bruhs) { - FontRenderers.getRenderer().drawString(matrices,bruh.content,x+xOffset,y+heightPerLine()/2d-FontRenderers.getRenderer().getFontHeight()/2d,0xBBBBBB); - xOffset += bruh.width+7; + FontRenderers.getRenderer().drawString(matrices, bruh.content, x + xOffset, y + heightPerLine() / 2d - FontRenderers.getRenderer().getFontHeight() / 2d, 0xBBBBBB); + xOffset += bruh.width + 7; } - Renderer.R2D.renderQuad(matrices,Color.WHITE,x,y+yOffset,x+w,y+yOffset+1); - ClipStack.globalInstance.addWindow(matrices, new Rectangle(x,y+yOffset,x+w,y+h)); + Renderer.R2D.renderQuad(matrices, Color.WHITE, x, y + yOffset, x + w, y + yOffset + 1); + ClipStack.globalInstance.addWindow(matrices, new Rectangle(x, y + yOffset, x + w, y + h)); matrices.push(); - matrices.translate(0, scroller.getScroll(),0); + matrices.translate(0, scroller.getScroll(), 0); for (LogEntry log : logs) { double finalYOffset = yOffset; log.additionalProps.forEach((s, s2) -> { int index = bruhs.indexOf(new Bruh(s, 0)); double xOffsetToConsider = 4; - for(int i = 0;i bruh.width+7).reduce(Double::sum).orElse(0d)+4; - FontRenderers.getRenderer().drawString(matrices,log.msg,x+xO,y+yOffset+heightPerLine()/2d-FontRenderers.getRenderer().getFontHeight()/2d,0xFFFFFF); + double xO = bruhs.stream().map(bruh -> bruh.width + 7).reduce(Double::sum).orElse(0d) + 4; + FontRenderers.getRenderer().drawString(matrices, log.msg, x + xO, y + yOffset + heightPerLine() / 2d - FontRenderers.getRenderer().getFontHeight() / 2d, 0xFFFFFF); yOffset += heightPerLine(); } matrices.pop(); @@ -216,7 +222,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public boolean mouseScrolled(double mouseX, double mouseY, double amount) { - if (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h) { + if (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h) { double contentHeight = contentHeight(); double elScroll = contentHeight - h; scroller.setBounds(0, elScroll); @@ -224,22 +230,45 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT } return Element.super.mouseScrolled(mouseX, mouseY, amount); } + + public record LogEntry(Map 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 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(); - ClipStack.globalInstance.addWindow(matrices, new Rectangle(x,y,x+w,y+h)); - matrices.translate(x, y+s.getScroll(), 0); + ClipStack.globalInstance.addWindow(matrices, new Rectangle(x, y, x + w, y + h)); + matrices.translate(x, y + s.getScroll(), 0); for (Drawable drawable : aww) { - drawable.render(matrices, (int) (mouseX-x), (int) (mouseY-y-s.getScroll()), delta); + drawable.render(matrices, (int) (mouseX - x), (int) (mouseY - y - s.getScroll()), delta); } ClipStack.globalInstance.popWindow(); matrices.pop(); @@ -266,7 +295,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { for (Element element : aww) { - if (element.mouseClicked(mouseX-x, mouseY-y-s.getScroll(), button)) return true; + if (element.mouseClicked(mouseX - x, mouseY - y - s.getScroll(), button)) return true; } return Element.super.mouseClicked(mouseX, mouseY, button); } @@ -274,7 +303,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { for (Element element : aww) { - if (element.mouseReleased(mouseX-x, mouseY-y-s.getScroll(), button)) return true; + if (element.mouseReleased(mouseX - x, mouseY - y - s.getScroll(), button)) return true; } return Element.super.mouseReleased(mouseX, mouseY, button); } @@ -282,7 +311,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { for (Element element : aww) { - if (element.mouseDragged(mouseX-x, mouseY-y, button, deltaX, deltaY)) return true; + if (element.mouseDragged(mouseX - x, mouseY - y, button, deltaX, deltaY)) return true; } return Element.super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); } @@ -291,9 +320,9 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT public boolean mouseScrolled(double mouseX, double mouseY, double amount) { double he = 0; for (AccountViewerWidget accountViewerWidget : aww) { - he = Math.max(he, accountViewerWidget.y+ accountViewerWidget.height); + he = Math.max(he, accountViewerWidget.y + accountViewerWidget.height); } - if (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h) { + if (mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h) { double elScroll = he - h; s.setBounds(0, elScroll); s.scroll(amount); @@ -304,7 +333,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { for (Element element : aww) { - if(element.keyPressed(keyCode, scanCode, modifiers)) return true; + if (element.keyPressed(keyCode, scanCode, modifiers)) return true; } return Element.super.keyPressed(keyCode, scanCode, modifiers); } @@ -312,7 +341,7 @@ public class OnlineServicesDashboardScreen extends ClientScreen implements FastT @Override public boolean keyReleased(int keyCode, int scanCode, int modifiers) { for (Element element : aww) { - if(element.keyReleased(keyCode, scanCode, modifiers)) return true; + if (element.keyReleased(keyCode, scanCode, modifiers)) return true; } return Element.super.keyReleased(keyCode, scanCode, modifiers); } diff --git a/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java b/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java index 8a8651e..65ff34b 100644 --- a/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java +++ b/src/main/java/net/shadow/client/feature/module/impl/misc/IRC.java @@ -20,10 +20,12 @@ 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) + + @EventListener(type = EventType.PACKET_SEND) void onPackSent(PacketEvent pe) { if (pe.getPacket() instanceof ChatMessageC2SPacket msg) { String m = msg.getChatMessage(); @@ -46,7 +48,7 @@ public class IRC extends Module { setEnabled(false); return; } - this.wsS = new IRCWebSocket(URI.create(ShadowAPIWrapper.BASE_WS+"/irc"),ShadowAPIWrapper.getAuthKey(),()-> { + this.wsS = new IRCWebSocket(URI.create(ShadowAPIWrapper.BASE_WS + "/irc"), ShadowAPIWrapper.getAuthKey(), () -> { this.wsS = null; if (this.isEnabled()) this.setEnabled(false); }); diff --git a/src/main/java/net/shadow/client/helper/IRCWebSocket.java b/src/main/java/net/shadow/client/helper/IRCWebSocket.java index c28eb8f..fbaa6f8 100644 --- a/src/main/java/net/shadow/client/helper/IRCWebSocket.java +++ b/src/main/java/net/shadow/client/helper/IRCWebSocket.java @@ -17,6 +17,54 @@ import java.net.URI; import java.util.Map; public class IRCWebSocket extends WebSocketClient { + String authToken; + Runnable onClose; + public IRCWebSocket(URI serverUri, String authToken, Runnable onClose) { + super(serverUri, Map.of("Authorization", authToken)); + this.authToken = authToken; + this.onClose = onClose; + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + Utils.Logging.success("Connected to IRC"); + } + + @Override + public void onMessage(String message) { + Packet p = new Gson().fromJson(message, Packet.class); + switch (p.id) { + case "message" -> { + String uname = p.data.get("who").toString(); + String msg = p.data.get("message").toString(); + ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s[%s] %s", Formatting.AQUA, Formatting.BLUE, uname, msg)), false); + } + case "userJoined" -> { + String uname = p.data.get("who").toString(); + ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s%s joined the IRC", Formatting.AQUA, Formatting.GREEN, uname)), false); + } + case "userLeft" -> { + String uname = p.data.get("who").toString(); + ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s%s left the IRC", Formatting.AQUA, Formatting.RED, uname)), false); + } + case "connectFailed" -> { + String reason = p.data.get("reason").toString(); + Utils.Logging.error("Failed to establish connection, server said: " + reason); + } + } + } + + @Override + public void onClose(int code, String reason, boolean remote) { + Utils.Logging.error("IRC Disconnected"); + this.onClose.run(); + } + + @Override + public void onError(Exception ex) { + ex.printStackTrace(); + } + @AllArgsConstructor public static class Packet { @@ -35,51 +83,4 @@ public class IRCWebSocket extends WebSocketClient { '}'; } } - String authToken; - Runnable onClose; - public IRCWebSocket(URI serverUri, String authToken, Runnable onClose) { - super(serverUri, Map.of("Authorization", authToken)); - this.authToken = authToken; - this.onClose = onClose; - } - - @Override - public void onOpen(ServerHandshake handshakedata) { - Utils.Logging.success("Connected to IRC"); - } - - @Override - public void onMessage(String message) { - Packet p = new Gson().fromJson(message, Packet.class); - switch(p.id) { - case "message" -> { - String uname = p.data.get("who").toString(); - String msg = p.data.get("message").toString(); - ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s[%s] %s", Formatting.AQUA, Formatting.BLUE, uname, msg)), false); - } - case "userJoined" -> { - String uname = p.data.get("who").toString(); - ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s%s joined the IRC", Formatting.AQUA, Formatting.GREEN, uname)), false); - } - case "userLeft" -> { - String uname = p.data.get("who").toString(); - ShadowMain.client.player.sendMessage(Text.of(String.format("%s[IRC] %s%s left the IRC", Formatting.AQUA, Formatting.RED, uname)), false); - } - case "connectFailed" -> { - String reason = p.data.get("reason").toString(); - Utils.Logging.error("Failed to establish connection, server said: "+reason); - } - } - } - - @Override - public void onClose(int code, String reason, boolean remote) { - Utils.Logging.error("IRC Disconnected"); - this.onClose.run(); - } - - @Override - public void onError(Exception ex) { - ex.printStackTrace(); - } } diff --git a/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java b/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java index 9851ecc..7662857 100644 --- a/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java +++ b/src/main/java/net/shadow/client/helper/ShadowAPIWrapper.java @@ -13,13 +13,15 @@ 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 { public static final String BASE_DOMAIN = "api.shadowclient.cf"; - public static final String BASE_URL = "https://"+BASE_DOMAIN; - public static final String BASE_WS = "wss://"+BASE_DOMAIN; + public static final String BASE_URL = "https://" + BASE_DOMAIN; + public static final String BASE_WS = "wss://" + BASE_DOMAIN; static String authKey = ""; static HttpClient client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build(); static Gson gson = new Gson(); @@ -37,8 +39,9 @@ public class ShadowAPIWrapper { static HttpResponse get(String path) { return request(path, "GET", HttpRequest.BodyPublishers.noBody()); } + static HttpResponse request(String path, String method, HttpRequest.BodyPublisher publisher) { - URI u = URI.create(BASE_URL+path); + URI u = URI.create(BASE_URL + path); HttpRequest request = HttpRequest.newBuilder().method(method, publisher).uri(u).header("Authorization", authKey).build(); try { return client.send(request, HttpResponse.BodyHandlers.ofString()); @@ -47,12 +50,15 @@ public class ShadowAPIWrapper { return null; } } + static HttpResponse 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; @@ -61,10 +67,11 @@ public class ShadowAPIWrapper { authKey = prevAuthKey; return false; } - Map info = gson.fromJson(resp.body(),Map.class); + Map info = gson.fromJson(resp.body(), Map.class); currentUserIsAdmin = (boolean) info.getOrDefault("isAdmin", false); return true; } + public static boolean attemptLogin(String username, String password) { String d = gson.toJson(Map.of( "username", username, @@ -72,12 +79,26 @@ public class ShadowAPIWrapper { )); HttpResponse uResp = post("/users/apiKeyForCreds", d); if (uResp == null) return false; - System.out.println(uResp.body()+": "+d); + System.out.println(uResp.body() + ": " + d); if (uResp.statusCode() != 200) return false; return loginWithKey(uResp.body()); } + + public static List getAccounts() { + HttpResponse 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 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 a = request("/items","PUT", HttpRequest.BodyPublishers.ofString(gson.toJson(Map.of( + HttpResponse a = request("/items", "PUT", HttpRequest.BodyPublishers.ofString(gson.toJson(Map.of( "itemName", Registry.ITEM.getId(stack.getItem()).getPath(), "itemNbt", new String(Base64.getEncoder().encode(stack.getOrCreateNbt().toString().getBytes(StandardCharsets.UTF_8))) )))); @@ -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 + '\'' + + '}'; + } + } } diff --git a/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java b/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java index 22d77fa..a4c6eb8 100644 --- a/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java +++ b/src/main/java/net/shadow/client/helper/ws/SimpleWebsocket.java @@ -14,6 +14,7 @@ import java.util.function.Consumer; public class SimpleWebsocket extends WebSocketClient { Runnable onClose; Consumer onMessage; + public SimpleWebsocket(URI serverUri, Map headers, Runnable c, Consumer msg) { super(serverUri, headers); this.onClose = c;