proto admin dashboard now has the ability to delete accounts + reformat

This commit is contained in:
0x3C50 2022-04-28 05:39:31 +02:00
parent a561a8025d
commit 7e99e9f9d6
7 changed files with 192 additions and 121 deletions

View file

@ -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");

View file

@ -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());
});

View file

@ -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();

View file

@ -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) {

View file

@ -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 +
'}';
}
}
}

View file

@ -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 + '\'' +
'}';
}
}
}

View file

@ -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;