+ Server Block [WIP]

This commit is contained in:
Nicolas BARBOTIN 2018-02-08 22:29:49 +01:00
parent 9649f8ab7d
commit b3aede2fee
8 changed files with 246 additions and 41 deletions

View File

@ -6,6 +6,7 @@ This is the unfinished port of the WebDisplays mod for Minecraft 1.12.2. The tex
* Read config (see "Config elements" below)
* Miniserv timeout
* Recipe for server block
* del command
### TODO
* French translations

View File

@ -14,15 +14,15 @@ import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.miniserv.client.Client;
import net.montoyo.wd.miniserv.client.ClientTask;
import net.montoyo.wd.miniserv.client.ClientTaskGetFileList;
import net.montoyo.wd.miniserv.client.ClientTaskGetQuota;
import net.montoyo.wd.miniserv.Constants;
import net.montoyo.wd.miniserv.client.*;
import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.utilities.NameUUIDPair;
import net.montoyo.wd.utilities.Util;
import org.lwjgl.input.Keyboard;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -38,6 +38,8 @@ public class GuiServer extends WDScreen {
private static final ResourceLocation BG_IMAGE = new ResourceLocation("webdisplays", "textures/gui/server_bg.png");
private static final ResourceLocation FG_IMAGE = new ResourceLocation("webdisplays", "textures/gui/server_fg.png");
private static final HashMap<String, Method> COMMAND_MAP = new HashMap<>();
private static final int MAX_LINE_LEN = 30;
private static final int MAX_LINES = 12;
private final NameUUIDPair owner;
private final ArrayList<String> lines = new ArrayList<>();
@ -55,6 +57,13 @@ public class GuiServer extends WDScreen {
private int accessState = -1;
private PositionedSoundRecord accessSound;
//Upload wizard
private boolean uploadWizard;
private int selectedLine = -1;
private File uploadDir;
private File[] uploadFiles;
private int uploadOffset;
public GuiServer(NameUUIDPair owner) {
this.owner = owner;
//userPrompt = owner.name + "@miniserv$ ";
@ -65,6 +74,7 @@ public class GuiServer extends WDScreen {
lines.add("MiniServ 1.0");
lines.add(tr("info"));
uploadCD(FileSystemView.getFileSystemView().getDefaultDirectory());
}
private static String tr(String key, Object ... args) {
@ -86,8 +96,13 @@ public class GuiServer extends WDScreen {
x += 18;
y += 18;
for(String line: lines) {
fontRenderer.drawString(line, x, y, 0xFFFFFFFF, false);
for(int i = 0; i < lines.size(); i++) {
if(selectedLine == i) {
drawWhiteQuad(x - 1, y - 2, fontRenderer.getStringWidth(lines.get(i)) + 1, 12);
fontRenderer.drawString(lines.get(i), x, y, 0xFF129700, false);
} else
fontRenderer.drawString(lines.get(i), x, y, 0xFFFFFFFF, false);
y += 12;
}
@ -96,22 +111,8 @@ public class GuiServer extends WDScreen {
x = fontRenderer.drawString(prompt, x, y, 0xFFFFFFFF, false);
}
if(blinkTime < 5) {
double xd = (double) (x + 1);
double yd = (double) y;
double zd = (double) zLevel;
GlStateManager.disableTexture2D();
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
Tessellator t = Tessellator.getInstance();
BufferBuilder bb = t.getBuffer();
bb.begin(GL_QUADS, DefaultVertexFormats.POSITION);
bb.pos(xd, yd + 8.0f, zd).endVertex();
bb.pos(xd + 6.0f, yd + 8.0f, zd).endVertex();
bb.pos(xd + 6.0f, yd, zd).endVertex();
bb.pos(xd, yd, zd).endVertex();
t.draw();
}
if(!uploadWizard && blinkTime < 5)
drawWhiteQuad(x + 1, y, 6, 8);
GlStateManager.disableAlpha();
GlStateManager.enableTexture2D();
@ -120,6 +121,27 @@ public class GuiServer extends WDScreen {
mc.renderEngine.bindTexture(FG_IMAGE);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
drawTexturedModalRect((width - 256) / 2, (height - 176) / 2, 0, 0, 256, 176);
GlStateManager.enableAlpha();
}
private void drawWhiteQuad(int x, int y, int w, int h) {
double xd = (double) x;
double xd2 = (double) (x + w);
double yd = (double) y;
double yd2 = (double) (y + h);
double zd = (double) zLevel;
GlStateManager.disableTexture2D();
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
Tessellator t = Tessellator.getInstance();
BufferBuilder bb = t.getBuffer();
bb.begin(GL_QUADS, DefaultVertexFormats.POSITION);
bb.pos(xd, yd2, zd).endVertex();
bb.pos(xd2, yd2, zd).endVertex();
bb.pos(xd2, yd, zd).endVertex();
bb.pos(xd, yd, zd).endVertex();
t.draw();
GlStateManager.enableTexture2D();
}
@Override
@ -159,24 +181,51 @@ public class GuiServer extends WDScreen {
@Override
public void handleKeyboardInput() throws IOException {
if(!promptLocked && Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_UP) {
if(lastCmd != null)
prompt = lastCmd;
boolean keyState = Keyboard.getEventKeyState();
int keyCode = Keyboard.getEventKey();
return;
if(uploadWizard) {
if(keyState) {
if(keyCode == Keyboard.KEY_UP) {
if(--selectedLine < 3)
selectedLine = MAX_LINES - 1;
} else if(keyCode == Keyboard.KEY_DOWN) {
if(++selectedLine >= MAX_LINES)
selectedLine = 3;
}
}
if(keyCode == Keyboard.KEY_ESCAPE) {
lines.clear();
promptLocked = false;
uploadWizard = false;
selectedLine = -1;
return; //Don't let the screen handle this
}
super.handleKeyboardInput();
} else {
super.handleKeyboardInput();
if(keyState) {
if(keyCode == Keyboard.KEY_L && (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)))
lines.clear();
else if(keyCode == Keyboard.KEY_UP) {
if(lastCmd != null) {
String tmp = prompt;
prompt = lastCmd;
lastCmd = tmp;
}
}
}
}
super.handleKeyboardInput();
if(Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_L && (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)))
lines.clear();
}
@Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
super.keyTyped(typedChar, keyCode);
if(promptLocked)
if(promptLocked || uploadWizard)
return;
if(keyCode == Keyboard.KEY_BACK) {
@ -190,7 +239,7 @@ public class GuiServer extends WDScreen {
prompt = "";
} else
writeLine(userPrompt);
} else if(prompt.length() + 1 < 30 && typedChar >= 32 && typedChar <= 126)
} else if(prompt.length() + 1 < MAX_LINE_LEN && typedChar >= 32 && typedChar <= 126)
prompt = prompt + typedChar;
blinkTime = 0;
@ -223,7 +272,8 @@ public class GuiServer extends WDScreen {
}
private void writeLine(String line) {
while(lines.size() >= 11)
final int maxl = uploadWizard ? MAX_LINES : (MAX_LINES - 1); //Cuz prompt is hidden
while(lines.size() >= maxl)
lines.remove(0);
lines.add(line);
@ -268,6 +318,18 @@ public class GuiServer extends WDScreen {
currentTask = null;
}
private static String trimStringL(String str) {
int delta = str.length() - MAX_LINE_LEN;
if(delta <= 0)
return str;
return "..." + str.substring(delta + 3);
}
private static String trimStringR(String str) {
return (str.length() <= MAX_LINE_LEN) ? str : (str.substring(0, MAX_LINE_LEN - 3) + "...");
}
@CommandHandler("clear")
public void commandClear() {
lines.clear();
@ -343,4 +405,70 @@ public class GuiServer extends WDScreen {
queueTask(task);
}
@CommandHandler("url")
public void commandURL(String[] args) {
if(args.length < 1) {
writeLine(tr("urlarg"));
return;
}
String fname = Util.join(args, " ");
if(Util.isFileNameInvalid(fname)) {
writeLine(tr("nameerr"));
return;
}
ClientTaskCheckFile task = new ClientTaskCheckFile(owner.uuid, fname);
task.setFinishCallback((t) -> {
int status = t.getStatus();
if(status == 0) {
writeLine(tr("urlcopied"));
setClipboardString(t.getURL());
} else if(status == Constants.GETF_STATUS_NOT_FOUND)
writeLine(tr("notfound"));
else
writeLine(tr("error2", status));
clearTask();
});
queueTask(task);
}
private void uploadCD(File newDir) {
try {
uploadDir = newDir.getCanonicalFile();
} catch(IOException ex) {
uploadDir = newDir;
}
uploadFiles = uploadDir.listFiles();
if(uploadFiles == null)
uploadFiles = new File[0];
else
uploadFiles = Arrays.stream(uploadFiles).filter(f -> !f.isHidden() && (f.isDirectory() || (f.isFile() && !Util.isFileNameInvalid(f.getName())))).toArray(File[]::new);
}
private void updateUploadScreen() {
lines.clear();
lines.add("Choose a file to upload");
lines.add(trimStringL(uploadDir.getPath()));
lines.add("");
lines.add("[Parent]");
final int maxl = Math.min(MAX_LINES - 4, uploadFiles.length);
for(int i = uploadOffset; i < maxl; i++)
lines.add(trimStringR(uploadFiles[i].getName()));
}
@CommandHandler("upload")
public void commandUpload() {
uploadWizard = true;
promptLocked = true;
selectedLine = 3;
uploadOffset = 0;
updateUploadScreen();
}
}

View File

@ -287,6 +287,8 @@ public class Client extends AbstractClient implements Runnable {
public void handleGetFile(DataInputStream dis) throws IOException {
if(currentTask instanceof ClientTaskGetFile)
((ClientTaskGetFile) currentTask).onGetFileResponse(dis.readByte());
else if(currentTask instanceof ClientTaskCheckFile)
((ClientTaskCheckFile) currentTask).onStatus(dis.readByte());
}
@PacketHandler(PacketID.FILE_PART)

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
*/
package net.montoyo.wd.miniserv.client;
import net.montoyo.wd.miniserv.Constants;
import net.montoyo.wd.miniserv.OutgoingPacket;
import net.montoyo.wd.miniserv.PacketID;
import java.util.UUID;
public class ClientTaskCheckFile extends ClientTask<ClientTaskCheckFile> {
private final UUID uuid;
private final String fname;
private int status = Constants.GETF_STATUS_INTERNAL_ERROR;
public ClientTaskCheckFile(UUID id, String name) {
uuid = id;
fname = name;
runCallbackOnMcThread = true;
}
@Override
public void start() {
OutgoingPacket pkt = new OutgoingPacket();
pkt.writeByte(PacketID.GET_FILE.ordinal());
pkt.writeLong(uuid.getMostSignificantBits());
pkt.writeLong(uuid.getLeastSignificantBits());
pkt.writeString(fname);
pkt.writeBoolean(false);
client.sendPacket(pkt);
}
@Override
public void abort() {
}
public void onStatus(int s) {
status = s;
client.nextTask();
}
public int getStatus() {
return status;
}
public String getURL() {
return ((new StringBuilder("wd://"))).append(uuid.toString()).append('/').append(fname).toString();
}
}

View File

@ -40,6 +40,7 @@ public class ClientTaskGetFile extends ClientTask<ClientTaskGetFile> {
pkt.writeLong(uuid.getMostSignificantBits());
pkt.writeLong(uuid.getLeastSignificantBits());
pkt.writeString(fname);
pkt.writeBoolean(true);
client.sendPacket(pkt);
}

View File

@ -214,6 +214,7 @@ public class ServerClient extends AbstractClient {
long msb = dis.readLong();
long lsb = dis.readLong();
String fname = readString(dis);
boolean doQuery = dis.readBoolean();
OutgoingPacket rep = new OutgoingPacket();
rep.writeByte(PacketID.GET_FILE.ordinal());
@ -224,13 +225,16 @@ public class ServerClient extends AbstractClient {
UUID user = new UUID(msb, lsb);
File fle = new File(Server.getInstance().getDirectory(), user.toString() + File.separatorChar + fname);
try {
rep.setOnFinishAction(new SendFileCallback(fle));
rep.writeByte(0);
sendingFile = true;
} catch(FileNotFoundException ex) {
rep.writeByte(Constants.GETF_STATUS_NOT_FOUND);
}
if(doQuery) {
try {
rep.setOnFinishAction(new SendFileCallback(fle));
rep.writeByte(0);
sendingFile = true;
} catch(FileNotFoundException ex) {
rep.writeByte(Constants.GETF_STATUS_NOT_FOUND);
}
} else
rep.writeByte((fle.exists() && fle.isFile()) ? 0 : Constants.GETF_STATUS_NOT_FOUND);
}
sendPacket(rep);

View File

@ -14,6 +14,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringJoiner;
public abstract class Util {
@ -242,4 +243,11 @@ public abstract class Util {
return String.format("%.2f %s", d, SIZES[size]);
}
public static String join(String[] array, String sep) {
StringJoiner j = new StringJoiner(sep);
Arrays.stream(array).forEach(j::add);
return j.toString();
}
}

View File

@ -114,6 +114,7 @@ webdisplays.side.east=East
webdisplays.server.info=Type "help" if you need some.
webdisplays.server.unknowncmd=Unknown command.
webdisplays.server.error=Internal error. Check logs.
webdisplays.server.error2=Internal error %d. Check logs.
webdisplays.server.argerror=Unrecognized argument.
webdisplays.server.queryerr=Query error, check logs.
webdisplays.server.errowner=Only the owner can access this.
@ -121,6 +122,10 @@ webdisplays.server.timeout=Query timed out. Check logs.
webdisplays.server.ownername=Owner name: %s
webdisplays.server.owneruuid=Owner UUID:
webdisplays.server.quota=%s/%s used
webdisplays.server.urlarg=Missing file name argument
webdisplays.server.nameerr=Invalid file name
webdisplays.server.urlcopied=Copied URL to clipboard.
webdisplays.server.notfound=File not found
webdisplays.server.help.help=Displays this text
webdisplays.server.help.clear=Clears the screen
webdisplays.server.help.exit=Leaves this console
@ -128,3 +133,5 @@ webdisplays.server.help.access=§kNo help data
webdisplays.server.help.owner=Displays the server owner
webdisplays.server.help.quota=Displays the storage quota
webdisplays.server.help.ls=Lists the files on this server
webdisplays.server.help.url=Copies a file URL into your clipboard
webdisplays.server.help.upload=Opens the upload wizard