mirror of
https://github.com/Miasmusa/Shadow.git
synced 2024-11-14 19:04:54 -05:00
proto admin dashboard, todo
This commit is contained in:
parent
be06d0df01
commit
a561a8025d
4 changed files with 383 additions and 3 deletions
|
@ -4,7 +4,11 @@
|
|||
|
||||
package net.shadow.client.feature.command.impl;
|
||||
|
||||
import net.shadow.client.ShadowMain;
|
||||
import net.shadow.client.feature.command.Command;
|
||||
import net.shadow.client.feature.gui.screen.OnlineServicesDashboardScreen;
|
||||
import net.shadow.client.helper.ShadowAPIWrapper;
|
||||
import net.shadow.client.helper.util.Utils;
|
||||
|
||||
public class Test extends Command {
|
||||
public Test() {
|
||||
|
@ -13,6 +17,12 @@ public class Test extends Command {
|
|||
|
||||
@Override
|
||||
public void onExecute(String[] args) {
|
||||
|
||||
if (ShadowAPIWrapper.getAuthKey() != null && ShadowAPIWrapper.isCurrentUserAdmin()) {
|
||||
Utils.TickManager.runInNTicks(5, () -> {
|
||||
ShadowMain.client.setScreen(new OnlineServicesDashboardScreen());
|
||||
});
|
||||
} else {
|
||||
error("not logged in or not admin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved.
|
||||
*/
|
||||
|
||||
package net.shadow.client.feature.gui.screen;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.Selectable;
|
||||
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.shadow.client.feature.gui.FastTickable;
|
||||
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.render.ClipStack;
|
||||
import net.shadow.client.helper.render.Rectangle;
|
||||
import net.shadow.client.helper.render.Renderer;
|
||||
import net.shadow.client.helper.render.Scroller;
|
||||
import net.shadow.client.helper.ws.SimpleWebsocket;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.net.URI;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class OnlineServicesDashboardScreen extends ClientScreen implements FastTickable {
|
||||
long reconnectTime = System.currentTimeMillis();
|
||||
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();
|
||||
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")) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd/MM/yyyy");
|
||||
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;
|
||||
@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(dvw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFastTick() {
|
||||
if (reconnectTime != -1 && reconnectTime < System.currentTimeMillis()) {
|
||||
initSocket();
|
||||
reconnectTime = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderInternal(MatrixStack stack, int mouseX, int mouseY, float delta) {
|
||||
renderBackground(stack);
|
||||
super.renderInternal(stack, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
||||
for (Element child : this.children()) {
|
||||
if (child.mouseScrolled(mouseX, mouseY, amount)) return true;
|
||||
}
|
||||
return super.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
@RequiredArgsConstructor
|
||||
static
|
||||
class AccountViewerWidget implements Element, Drawable, Selectable, FastTickable {
|
||||
final String username, password;
|
||||
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);
|
||||
double h = FontRenderers.getRenderer().getFontHeight();
|
||||
double pad = height-h;
|
||||
|
||||
FontRenderers.getRenderer().drawString(matrices,username+":"+password,x+pad/2d,y+height/2d-h/2d,0xFFFFFF);
|
||||
deleteBtn.render(matrices, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionType getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendNarrations(NarrationMessageBuilder builder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFastTick() {
|
||||
deleteBtn.onFastTick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
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);
|
||||
List<Bruh> bruhs = new ArrayList<>();
|
||||
for (LogEntry log : logs) {
|
||||
log.additionalProps.forEach((s, s2) -> {
|
||||
if (bruhs.stream().noneMatch(bruh -> bruh.content.equals(s))) {
|
||||
bruhs.add(new Bruh(s, Math.max(FontRenderers.getRenderer().getStringWidth(s2), FontRenderers.getRenderer().getStringWidth(s))));
|
||||
} else {
|
||||
Bruh b = bruhs.stream().filter(bruh -> bruh.content.equals(s)).findFirst().orElseThrow();
|
||||
double w = Math.max(b.width, Math.max(FontRenderers.getRenderer().getStringWidth(s2), FontRenderers.getRenderer().getStringWidth(s)));
|
||||
bruhs.remove(b);
|
||||
bruhs.add(new Bruh(s, w));
|
||||
}
|
||||
});
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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<index;i++) {
|
||||
xOffsetToConsider += bruhs.get(i).width+7;
|
||||
}
|
||||
FontRenderers.getRenderer().drawString(matrices,s2,x+xOffsetToConsider,y+ finalYOffset +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();
|
||||
ClipStack.globalInstance.popWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionType getType() {
|
||||
return SelectionType.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendNarrations(NarrationMessageBuilder builder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFastTick() {
|
||||
scroller.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
||||
if (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h) {
|
||||
double contentHeight = contentHeight();
|
||||
double elScroll = contentHeight - h;
|
||||
scroller.setBounds(0, elScroll);
|
||||
scroller.scroll(amount);
|
||||
}
|
||||
return Element.super.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
}
|
||||
@RequiredArgsConstructor
|
||||
class AccountList implements Element, Drawable, Selectable, FastTickable {
|
||||
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();
|
||||
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);
|
||||
}
|
||||
ClipStack.globalInstance.popWindow();
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionType getType() {
|
||||
return SelectionType.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendNarrations(NarrationMessageBuilder builder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFastTick() {
|
||||
s.tick();
|
||||
for (Element element : aww) {
|
||||
if (element instanceof FastTickable ft) ft.onFastTick();
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
return Element.super.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
return Element.super.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
return Element.super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
||||
double he = 0;
|
||||
for (AccountViewerWidget accountViewerWidget : aww) {
|
||||
he = Math.max(he, accountViewerWidget.y+ accountViewerWidget.height);
|
||||
}
|
||||
if (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h) {
|
||||
double elScroll = he - h;
|
||||
s.setBounds(0, elScroll);
|
||||
s.scroll(amount);
|
||||
}
|
||||
return Element.super.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
for (Element element : aww) {
|
||||
if(element.keyPressed(keyCode, scanCode, modifiers)) return true;
|
||||
}
|
||||
return Element.super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
||||
for (Element element : aww) {
|
||||
if(element.keyReleased(keyCode, scanCode, modifiers)) return true;
|
||||
}
|
||||
return Element.super.keyReleased(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char chr, int modifiers) {
|
||||
for (Element element : aww) {
|
||||
if (element.charTyped(chr, modifiers)) return true;
|
||||
}
|
||||
return Element.super.charTyped(chr, modifiers);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,8 +20,8 @@ public class IRCWebSocket extends WebSocketClient {
|
|||
@AllArgsConstructor
|
||||
public static
|
||||
class Packet {
|
||||
String id;
|
||||
Map<String, Object> data;
|
||||
public String id;
|
||||
public Map<String, Object> data;
|
||||
|
||||
public String toRawPacket() {
|
||||
return new Gson().toJson(this);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved.
|
||||
*/
|
||||
|
||||
package net.shadow.client.helper.ws;
|
||||
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
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;
|
||||
this.onMessage = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake handshakedata) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
onMessage.accept(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int code, String reason, boolean remote) {
|
||||
onClose.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue