+ Server Block [almost finished]
This commit is contained in:
parent
b3aede2fee
commit
9789daa33e
|
|
@ -5,8 +5,6 @@ This is the unfinished port of the WebDisplays mod for Minecraft 1.12.2. The tex
|
||||||
* Peripheral: OpenComputers interface
|
* Peripheral: OpenComputers interface
|
||||||
* Read config (see "Config elements" below)
|
* Read config (see "Config elements" below)
|
||||||
* Miniserv timeout
|
* Miniserv timeout
|
||||||
* Recipe for server block
|
|
||||||
* del command
|
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
* French translations
|
* French translations
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.text.Collator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -38,7 +39,7 @@ public class GuiServer extends WDScreen {
|
||||||
private static final ResourceLocation BG_IMAGE = new ResourceLocation("webdisplays", "textures/gui/server_bg.png");
|
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 ResourceLocation FG_IMAGE = new ResourceLocation("webdisplays", "textures/gui/server_fg.png");
|
||||||
private static final HashMap<String, Method> COMMAND_MAP = new HashMap<>();
|
private static final HashMap<String, Method> COMMAND_MAP = new HashMap<>();
|
||||||
private static final int MAX_LINE_LEN = 30;
|
private static final int MAX_LINE_LEN = 32;
|
||||||
private static final int MAX_LINES = 12;
|
private static final int MAX_LINES = 12;
|
||||||
|
|
||||||
private final NameUUIDPair owner;
|
private final NameUUIDPair owner;
|
||||||
|
|
@ -48,8 +49,9 @@ public class GuiServer extends WDScreen {
|
||||||
private int blinkTime;
|
private int blinkTime;
|
||||||
private String lastCmd;
|
private String lastCmd;
|
||||||
private boolean promptLocked;
|
private boolean promptLocked;
|
||||||
private long queryTime;
|
private volatile long queryTime;
|
||||||
private ClientTask<?> currentTask;
|
private ClientTask<?> currentTask;
|
||||||
|
private int selectedLine = -1;
|
||||||
|
|
||||||
//Access command
|
//Access command
|
||||||
private int accessTrials;
|
private int accessTrials;
|
||||||
|
|
@ -59,10 +61,12 @@ public class GuiServer extends WDScreen {
|
||||||
|
|
||||||
//Upload wizard
|
//Upload wizard
|
||||||
private boolean uploadWizard;
|
private boolean uploadWizard;
|
||||||
private int selectedLine = -1;
|
|
||||||
private File uploadDir;
|
private File uploadDir;
|
||||||
private File[] uploadFiles;
|
private final ArrayList<File> uploadFiles = new ArrayList<>();
|
||||||
private int uploadOffset;
|
private int uploadOffset;
|
||||||
|
private boolean uploadFirstIsParent;
|
||||||
|
private String uploadFilter = "";
|
||||||
|
private long uploadFilterTime;
|
||||||
|
|
||||||
public GuiServer(NameUUIDPair owner) {
|
public GuiServer(NameUUIDPair owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
|
@ -171,10 +175,22 @@ public class GuiServer extends WDScreen {
|
||||||
} else {
|
} else {
|
||||||
blinkTime = (blinkTime + 1) % 10;
|
blinkTime = (blinkTime + 1) % 10;
|
||||||
|
|
||||||
if(currentTask != null && System.currentTimeMillis() - queryTime >= 10000) {
|
if(currentTask != null) {
|
||||||
writeLine(tr("timeout"));
|
long queryTime;
|
||||||
currentTask.cancel();
|
synchronized(this) {
|
||||||
clearTask();
|
queryTime = this.queryTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(System.currentTimeMillis() - queryTime >= 10000) {
|
||||||
|
writeLine(tr("timeout"));
|
||||||
|
currentTask.cancel();
|
||||||
|
clearTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!uploadFilter.isEmpty() && System.currentTimeMillis() - uploadFilterTime >= 1000) {
|
||||||
|
Log.info("Upload filter cleared");
|
||||||
|
uploadFilter = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,19 +203,46 @@ public class GuiServer extends WDScreen {
|
||||||
if(uploadWizard) {
|
if(uploadWizard) {
|
||||||
if(keyState) {
|
if(keyState) {
|
||||||
if(keyCode == Keyboard.KEY_UP) {
|
if(keyCode == Keyboard.KEY_UP) {
|
||||||
if(--selectedLine < 3)
|
if(selectedLine > 3)
|
||||||
selectedLine = MAX_LINES - 1;
|
selectedLine--;
|
||||||
|
else if(uploadOffset > 0) {
|
||||||
|
uploadOffset--;
|
||||||
|
updateUploadScreen();
|
||||||
|
}
|
||||||
} else if(keyCode == Keyboard.KEY_DOWN) {
|
} else if(keyCode == Keyboard.KEY_DOWN) {
|
||||||
if(++selectedLine >= MAX_LINES)
|
if(selectedLine < MAX_LINES - 1)
|
||||||
selectedLine = 3;
|
selectedLine++;
|
||||||
|
else if(uploadOffset + selectedLine - 2 < uploadFiles.size()) {
|
||||||
|
uploadOffset++;
|
||||||
|
updateUploadScreen();
|
||||||
|
}
|
||||||
|
} else if(keyCode == Keyboard.KEY_PRIOR) {
|
||||||
|
selectedLine = 3;
|
||||||
|
int dst = uploadOffset - (MAX_LINES - 3);
|
||||||
|
if(dst < 0)
|
||||||
|
dst = 0;
|
||||||
|
|
||||||
|
selectFile(dst);
|
||||||
|
} else if(keyCode == Keyboard.KEY_NEXT) {
|
||||||
|
selectedLine = 3;
|
||||||
|
int dst = uploadOffset + (MAX_LINES - 3);
|
||||||
|
if(dst >= uploadFiles.size())
|
||||||
|
dst = uploadFiles.size() - 1;
|
||||||
|
|
||||||
|
selectFile(dst);
|
||||||
|
} else if(keyCode == Keyboard.KEY_RETURN || keyCode == Keyboard.KEY_NUMPADENTER) {
|
||||||
|
File file = uploadFiles.get(uploadOffset + selectedLine - 3);
|
||||||
|
|
||||||
|
if(file.isDirectory()) {
|
||||||
|
uploadCD(file);
|
||||||
|
updateUploadScreen();
|
||||||
|
} else
|
||||||
|
startFileUpload(file, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(keyCode == Keyboard.KEY_ESCAPE) {
|
if(keyCode == Keyboard.KEY_ESCAPE) {
|
||||||
lines.clear();
|
quitUploadWizard();
|
||||||
promptLocked = false;
|
|
||||||
uploadWizard = false;
|
|
||||||
selectedLine = -1;
|
|
||||||
return; //Don't let the screen handle this
|
return; //Don't let the screen handle this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,9 +251,16 @@ public class GuiServer extends WDScreen {
|
||||||
super.handleKeyboardInput();
|
super.handleKeyboardInput();
|
||||||
|
|
||||||
if(keyState) {
|
if(keyState) {
|
||||||
if(keyCode == Keyboard.KEY_L && (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)))
|
boolean ctrl = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
|
||||||
|
|
||||||
|
if(keyCode == Keyboard.KEY_L && ctrl)
|
||||||
lines.clear();
|
lines.clear();
|
||||||
else if(keyCode == Keyboard.KEY_UP) {
|
else if(keyCode == Keyboard.KEY_V && ctrl) {
|
||||||
|
prompt += getClipboardString();
|
||||||
|
|
||||||
|
if(prompt.length() > MAX_LINE_LEN)
|
||||||
|
prompt = prompt.substring(0, MAX_LINE_LEN);
|
||||||
|
} else if(keyCode == Keyboard.KEY_UP) {
|
||||||
if(lastCmd != null) {
|
if(lastCmd != null) {
|
||||||
String tmp = prompt;
|
String tmp = prompt;
|
||||||
prompt = lastCmd;
|
prompt = lastCmd;
|
||||||
|
|
@ -225,7 +275,24 @@ public class GuiServer extends WDScreen {
|
||||||
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||||
super.keyTyped(typedChar, keyCode);
|
super.keyTyped(typedChar, keyCode);
|
||||||
|
|
||||||
if(promptLocked || uploadWizard)
|
if(uploadWizard) {
|
||||||
|
boolean found = false;
|
||||||
|
uploadFilter += Character.toLowerCase(typedChar);
|
||||||
|
uploadFilterTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
for(int i = uploadFirstIsParent ? 1 : 0; i < uploadFiles.size(); i++) {
|
||||||
|
if(uploadFiles.get(i).getName().toLowerCase().startsWith(uploadFilter)) {
|
||||||
|
selectFile(i);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found && uploadFilter.length() == 1)
|
||||||
|
uploadFilter = "";
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if(promptLocked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(keyCode == Keyboard.KEY_BACK) {
|
if(keyCode == Keyboard.KEY_BACK) {
|
||||||
|
|
@ -293,6 +360,13 @@ public class GuiServer extends WDScreen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void quitUploadWizard() {
|
||||||
|
lines.clear();
|
||||||
|
promptLocked = false;
|
||||||
|
uploadWizard = false;
|
||||||
|
selectedLine = -1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuiClosed() {
|
public void onGuiClosed() {
|
||||||
super.onGuiClosed();
|
super.onGuiClosed();
|
||||||
|
|
@ -304,7 +378,7 @@ public class GuiServer extends WDScreen {
|
||||||
private boolean queueTask(ClientTask<?> task) {
|
private boolean queueTask(ClientTask<?> task) {
|
||||||
if(Client.getInstance().addTask(task)) {
|
if(Client.getInstance().addTask(task)) {
|
||||||
promptLocked = true;
|
promptLocked = true;
|
||||||
queryTime = System.currentTimeMillis();
|
queryTime = System.currentTimeMillis(); //No task is running so it's okay to have an unsynchronized access here
|
||||||
currentTask = task;
|
currentTask = task;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -336,9 +410,18 @@ public class GuiServer extends WDScreen {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandHandler("help")
|
@CommandHandler("help")
|
||||||
public void commandHelp() {
|
public void commandHelp(String[] args) {
|
||||||
for(String c : COMMAND_MAP.keySet())
|
if(args.length > 0) {
|
||||||
writeLine(c + " - " + tr("help." + c));
|
String cmd = args[0].toLowerCase();
|
||||||
|
|
||||||
|
if(COMMAND_MAP.containsKey(cmd))
|
||||||
|
writeLine(tr("help." + cmd));
|
||||||
|
else
|
||||||
|
writeLine(tr("unknowncmd"));
|
||||||
|
} else {
|
||||||
|
for(String c : COMMAND_MAP.keySet())
|
||||||
|
writeLine(c + " - " + tr("help." + c));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandHandler("exit")
|
@CommandHandler("exit")
|
||||||
|
|
@ -408,7 +491,7 @@ public class GuiServer extends WDScreen {
|
||||||
@CommandHandler("url")
|
@CommandHandler("url")
|
||||||
public void commandURL(String[] args) {
|
public void commandURL(String[] args) {
|
||||||
if(args.length < 1) {
|
if(args.length < 1) {
|
||||||
writeLine(tr("urlarg"));
|
writeLine(tr("fnamearg"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,11 +525,29 @@ public class GuiServer extends WDScreen {
|
||||||
uploadDir = newDir;
|
uploadDir = newDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadFiles = uploadDir.listFiles();
|
uploadFiles.clear();
|
||||||
if(uploadFiles == null)
|
File parent = uploadDir.getParentFile();
|
||||||
uploadFiles = new File[0];
|
|
||||||
else
|
if(parent != null && parent.exists()) {
|
||||||
uploadFiles = Arrays.stream(uploadFiles).filter(f -> !f.isHidden() && (f.isDirectory() || (f.isFile() && !Util.isFileNameInvalid(f.getName())))).toArray(File[]::new);
|
uploadFiles.add(parent);
|
||||||
|
uploadFirstIsParent = true;
|
||||||
|
} else
|
||||||
|
uploadFirstIsParent = false;
|
||||||
|
|
||||||
|
File[] children = uploadDir.listFiles();
|
||||||
|
if(children != null) {
|
||||||
|
Collator c = Collator.getInstance();
|
||||||
|
c.setStrength(Collator.SECONDARY);
|
||||||
|
c.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
|
||||||
|
|
||||||
|
Arrays.stream(children).filter(f -> !f.isHidden() && (f.isDirectory() || f.isFile())).sorted((a, b) -> c.compare(a.getName(), b.getName())).forEach(uploadFiles::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadOffset = 0;
|
||||||
|
uploadFilter = "";
|
||||||
|
|
||||||
|
if(uploadWizard)
|
||||||
|
selectedLine = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUploadScreen() {
|
private void updateUploadScreen() {
|
||||||
|
|
@ -455,20 +556,134 @@ public class GuiServer extends WDScreen {
|
||||||
lines.add("Choose a file to upload");
|
lines.add("Choose a file to upload");
|
||||||
lines.add(trimStringL(uploadDir.getPath()));
|
lines.add(trimStringL(uploadDir.getPath()));
|
||||||
lines.add("");
|
lines.add("");
|
||||||
lines.add("[Parent]");
|
|
||||||
|
|
||||||
final int maxl = Math.min(MAX_LINES - 4, uploadFiles.length);
|
for(int i = uploadOffset; i < uploadFiles.size() && lines.size() < MAX_LINES; i++) {
|
||||||
for(int i = uploadOffset; i < maxl; i++)
|
if(i == 0 && uploadFirstIsParent)
|
||||||
lines.add(trimStringR(uploadFiles[i].getName()));
|
lines.add("[Parent directory]");
|
||||||
|
else
|
||||||
|
lines.add(trimStringR(uploadFiles.get(i).getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectFile(int i) {
|
||||||
|
int pos = 3 + i - uploadOffset;
|
||||||
|
if(pos >= 3 && pos < MAX_LINES) {
|
||||||
|
selectedLine = pos;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadOffset = i;
|
||||||
|
if(uploadOffset + MAX_LINES - 3 > uploadFiles.size())
|
||||||
|
uploadOffset = uploadFiles.size() - MAX_LINES + 3;
|
||||||
|
|
||||||
|
updateUploadScreen();
|
||||||
|
selectedLine = 3 + i - uploadOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandHandler("upload")
|
@CommandHandler("upload")
|
||||||
public void commandUpload() {
|
public void commandUpload(String[] args) {
|
||||||
|
if(!mc.player.getGameProfile().getId().equals(owner.uuid)) {
|
||||||
|
writeLine(tr("errowner"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args.length > 0) {
|
||||||
|
File fle = new File(Util.join(args, " "));
|
||||||
|
if(!fle.exists()) {
|
||||||
|
writeLine(tr("notfound"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fle.isDirectory())
|
||||||
|
uploadCD(fle);
|
||||||
|
else if(fle.isFile()) {
|
||||||
|
startFileUpload(fle, false);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
writeLine(tr("notfound"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uploadWizard = true;
|
uploadWizard = true;
|
||||||
promptLocked = true;
|
promptLocked = true;
|
||||||
selectedLine = 3;
|
|
||||||
uploadOffset = 0;
|
uploadOffset = 0;
|
||||||
|
selectedLine = 3;
|
||||||
updateUploadScreen();
|
updateUploadScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CommandHandler("rm")
|
||||||
|
public void commandDelete(String[] args) {
|
||||||
|
if(!mc.player.getGameProfile().getId().equals(owner.uuid)) {
|
||||||
|
writeLine(tr("errowner"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args.length < 1) {
|
||||||
|
writeLine(tr("fnamearg"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String fname = Util.join(args, " ");
|
||||||
|
if(Util.isFileNameInvalid(fname)) {
|
||||||
|
writeLine(tr("nameerr"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientTaskDeleteFile task = new ClientTaskDeleteFile(fname);
|
||||||
|
task.setFinishCallback((t) -> {
|
||||||
|
int status = t.getStatus();
|
||||||
|
if(status == 1)
|
||||||
|
writeLine(tr("notfound"));
|
||||||
|
else if(status != 0)
|
||||||
|
writeLine(tr("error"));
|
||||||
|
|
||||||
|
clearTask();
|
||||||
|
});
|
||||||
|
|
||||||
|
queueTask(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startFileUpload(File f, boolean quit) {
|
||||||
|
if(quit)
|
||||||
|
quitUploadWizard();
|
||||||
|
|
||||||
|
if(Util.isFileNameInvalid(f.getName()) || f.getName().length() >= MAX_LINE_LEN - 3) {
|
||||||
|
writeLine(tr("nameerr"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientTaskUploadFile task;
|
||||||
|
try {
|
||||||
|
task = new ClientTaskUploadFile(f);
|
||||||
|
} catch(IOException ex) {
|
||||||
|
writeLine(tr("error"));
|
||||||
|
ex.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
task.setProgressCallback((cur, total) -> {
|
||||||
|
synchronized(GuiServer.this) {
|
||||||
|
queryTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
task.setFinishCallback(t -> {
|
||||||
|
int status = t.getUploadStatus();
|
||||||
|
if(status == 0)
|
||||||
|
writeLine(tr("upload.done"));
|
||||||
|
else if(status == Constants.FUPA_STATUS_FILE_EXISTS)
|
||||||
|
writeLine(tr("upload.exists"));
|
||||||
|
else if(status == Constants.FUPA_STATUS_EXCEEDS_QUOTA)
|
||||||
|
writeLine(tr("upload.quota"));
|
||||||
|
else
|
||||||
|
writeLine(tr("error2", status));
|
||||||
|
|
||||||
|
clearTask();
|
||||||
|
});
|
||||||
|
|
||||||
|
if(queueTask(task))
|
||||||
|
writeLine(tr("upload.uploading"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,6 @@ public abstract class AbstractClient {
|
||||||
packetHandlers[ph.value().ordinal()] = m;
|
packetHandlers[ph.value().ordinal()] = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < packetHandlers.length; i++) {
|
|
||||||
if(packetHandlers[i] == null)
|
|
||||||
Log.warning("AbstractClient: no packet handler for %s", PacketID.fromInt(i).toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void onWriteError();
|
protected abstract void onWriteError();
|
||||||
|
|
@ -67,17 +62,13 @@ public abstract class AbstractClient {
|
||||||
|
|
||||||
if(pid >= packetHandlers.length)
|
if(pid >= packetHandlers.length)
|
||||||
Log.error("Caught invalid packet ID %d", pid);
|
Log.error("Caught invalid packet ID %d", pid);
|
||||||
else {
|
else if(packetHandlers[pid] != null) {
|
||||||
Log.info("Received PID %s", PacketID.fromInt(pid).toString());
|
try {
|
||||||
|
packetHandlers[pid].invoke(this, dis); //This is slow, I know... sorry
|
||||||
if(packetHandlers[pid] != null) {
|
} catch(IllegalAccessException ex) {
|
||||||
try {
|
Log.errorEx("This shouldn't have happened", ex);
|
||||||
packetHandlers[pid].invoke(this, dis); //This is slow, I know... sorry
|
} catch(InvocationTargetException ex) {
|
||||||
} catch(IllegalAccessException ex) {
|
Log.warningEx("Caught exception while handling packet %d", ex.getTargetException(), pid);
|
||||||
Log.errorEx("This shouldn't have happened", ex);
|
|
||||||
} catch(InvocationTargetException ex) {
|
|
||||||
Log.warningEx("Caught exception while handling packet %d", ex.getTargetException(), pid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(IOException ex) {
|
} catch(IOException ex) {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ public enum PacketID {
|
||||||
FILE_STATUS, //S->C
|
FILE_STATUS, //S->C
|
||||||
GET_FILE, //C->S
|
GET_FILE, //C->S
|
||||||
QUOTA, //C->S and S->C
|
QUOTA, //C->S and S->C
|
||||||
LIST; //C->S and S->C
|
LIST, //C->S and S->C
|
||||||
|
DELETE; //C->S and S->C
|
||||||
|
|
||||||
public static PacketID fromInt(int i) {
|
public static PacketID fromInt(int i) {
|
||||||
PacketID[] values = values();
|
PacketID[] values = values();
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,12 @@ public class Client extends AbstractClient implements Runnable {
|
||||||
((ClientTaskGetFileList) currentTask).onFileList(files);
|
((ClientTaskGetFileList) currentTask).onFileList(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PacketHandler(PacketID.DELETE)
|
||||||
|
public void handleDelete(DataInputStream dis) throws IOException {
|
||||||
|
if(currentTask instanceof ClientTaskDeleteFile)
|
||||||
|
((ClientTaskDeleteFile) currentTask).onStatusPacket(dis.readByte());
|
||||||
|
}
|
||||||
|
|
||||||
public void nextTask() {
|
public void nextTask() {
|
||||||
if(currentTask != null)
|
if(currentTask != null)
|
||||||
currentTask.onFinished();
|
currentTask.onFinished();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.montoyo.wd.miniserv.client;
|
||||||
|
|
||||||
|
import net.montoyo.wd.miniserv.OutgoingPacket;
|
||||||
|
import net.montoyo.wd.miniserv.PacketID;
|
||||||
|
|
||||||
|
public class ClientTaskDeleteFile extends ClientTask<ClientTaskDeleteFile> {
|
||||||
|
|
||||||
|
private final String fname;
|
||||||
|
private int status;
|
||||||
|
|
||||||
|
public ClientTaskDeleteFile(String fname) {
|
||||||
|
this.fname = fname;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
OutgoingPacket pkt = new OutgoingPacket();
|
||||||
|
pkt.writeByte(PacketID.DELETE.ordinal());
|
||||||
|
pkt.writeString(fname);
|
||||||
|
client.sendPacket(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void abort() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStatusPacket(int s) {
|
||||||
|
status = s;
|
||||||
|
client.nextTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,7 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> implements Consumer<OutgoingPacket> {
|
public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> implements Consumer<OutgoingPacket> {
|
||||||
|
|
@ -25,11 +26,14 @@ public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> imple
|
||||||
private FileInputStream fis;
|
private FileInputStream fis;
|
||||||
private boolean abortFupa;
|
private boolean abortFupa;
|
||||||
private int uploadStatus;
|
private int uploadStatus;
|
||||||
|
private long uploadPos;
|
||||||
|
private BiConsumer<Long, Long> onProgress;
|
||||||
|
|
||||||
public ClientTaskUploadFile(File fle) throws IOException {
|
public ClientTaskUploadFile(File fle) throws IOException {
|
||||||
file = fle;
|
file = fle;
|
||||||
size = Files.size(fle.toPath());
|
size = Files.size(fle.toPath());
|
||||||
fis = new FileInputStream(fle);
|
fis = new FileInputStream(fle);
|
||||||
|
runCallbackOnMcThread = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -45,7 +49,7 @@ public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> imple
|
||||||
@Override
|
@Override
|
||||||
public void abort() {
|
public void abort() {
|
||||||
abortFupa = true;
|
abortFupa = true;
|
||||||
setUploadStatus(Constants.FUPA_STATUS_CONNECTION_LOST);
|
uploadStatus = Constants.FUPA_STATUS_CONNECTION_LOST;
|
||||||
Util.silentClose(fis);
|
Util.silentClose(fis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,14 +60,14 @@ public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> imple
|
||||||
accept(null);
|
accept(null);
|
||||||
} else {
|
} else {
|
||||||
Util.silentClose(fis);
|
Util.silentClose(fis);
|
||||||
setUploadStatus(status);
|
uploadStatus = status;
|
||||||
client.nextTask();
|
client.nextTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUploadFinishedStatus(int status) {
|
public void onUploadFinishedStatus(int status) {
|
||||||
abortFupa = true; //This isn't necessary, but just in case...
|
abortFupa = true; //This isn't necessary, but just in case...
|
||||||
setUploadStatus(status);
|
uploadStatus = status;
|
||||||
client.nextTask();
|
client.nextTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,6 +95,11 @@ public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> imple
|
||||||
pkt.writeBytes(UPLOAD_BUFFER, 0, rd);
|
pkt.writeBytes(UPLOAD_BUFFER, 0, rd);
|
||||||
client.sendPacket(pkt);
|
client.sendPacket(pkt);
|
||||||
|
|
||||||
|
if(onProgress != null) {
|
||||||
|
uploadPos += (long) rd;
|
||||||
|
onProgress.accept(uploadPos, size);
|
||||||
|
}
|
||||||
|
|
||||||
if(rd > 0) {
|
if(rd > 0) {
|
||||||
pkt.setOnFinishAction(this);
|
pkt.setOnFinishAction(this);
|
||||||
return;
|
return;
|
||||||
|
|
@ -100,19 +109,12 @@ public class ClientTaskUploadFile extends ClientTask<ClientTaskUploadFile> imple
|
||||||
Util.silentClose(file);
|
Util.silentClose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUploadStatus(int val) {
|
public int getUploadStatus() {
|
||||||
synchronized(this) {
|
return uploadStatus;
|
||||||
uploadStatus = val;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUploadStatus() {
|
public void setProgressCallback(BiConsumer<Long, Long> onProgress) {
|
||||||
int ret;
|
this.onProgress = onProgress;
|
||||||
synchronized(this) {
|
|
||||||
ret = uploadStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.Selector;
|
import java.nio.channels.Selector;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
@ -278,6 +279,39 @@ public class ServerClient extends AbstractClient {
|
||||||
sendPacket(pkt);
|
sendPacket(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PacketHandler(PacketID.DELETE)
|
||||||
|
public void handleDelete(DataInputStream dis) throws IOException {
|
||||||
|
String fname = readString(dis);
|
||||||
|
int status = 2;
|
||||||
|
|
||||||
|
if(!Util.isFileNameInvalid(fname)) {
|
||||||
|
File file = new File(userDir, fname);
|
||||||
|
|
||||||
|
if(file.exists() && file.isFile()) {
|
||||||
|
try {
|
||||||
|
long sz = Files.size(file.toPath());
|
||||||
|
|
||||||
|
if(file.delete()) {
|
||||||
|
quota -= sz;
|
||||||
|
if(quota < 0)
|
||||||
|
quota = 0;
|
||||||
|
|
||||||
|
saveQuota();
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
} catch(IOException ex) {
|
||||||
|
Log.errorEx("Couldn't get size of file %s of user %s for removal", ex, file.getAbsolutePath(), uuid.toString());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutgoingPacket ret = new OutgoingPacket();
|
||||||
|
ret.writeByte(PacketID.DELETE.ordinal());
|
||||||
|
ret.writeByte(status);
|
||||||
|
sendPacket(ret);
|
||||||
|
}
|
||||||
|
|
||||||
private void finishUpload(int status) {
|
private void finishUpload(int status) {
|
||||||
if(currentFile != null) {
|
if(currentFile != null) {
|
||||||
OutgoingPacket pkt = new OutgoingPacket();
|
OutgoingPacket pkt = new OutgoingPacket();
|
||||||
|
|
@ -289,14 +323,17 @@ public class ServerClient extends AbstractClient {
|
||||||
currentFile = null;
|
currentFile = null;
|
||||||
|
|
||||||
quota += currentFileSize;
|
quota += currentFileSize;
|
||||||
|
saveQuota();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
private void saveQuota() {
|
||||||
DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File(userDir, ".quota")));
|
try {
|
||||||
dos.writeLong(quota);
|
DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File(userDir, ".quota")));
|
||||||
Util.silentClose(dos);
|
dos.writeLong(quota);
|
||||||
} catch(IOException ex) {
|
Util.silentClose(dos);
|
||||||
Log.errorEx("Could not save quota data for user %s", ex, uuid.toString());
|
} catch(IOException ex) {
|
||||||
}
|
Log.errorEx("Could not save quota data for user %s", ex, uuid.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@
|
||||||
"webdisplays:redctrl1",
|
"webdisplays:redctrl1",
|
||||||
"webdisplays:redctrl2",
|
"webdisplays:redctrl2",
|
||||||
"webdisplays:stonekey",
|
"webdisplays:stonekey",
|
||||||
"webdisplays:keyboard"
|
"webdisplays:keyboard",
|
||||||
|
"webdisplays:server"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,10 +122,14 @@ webdisplays.server.timeout=Query timed out. Check logs.
|
||||||
webdisplays.server.ownername=Owner name: %s
|
webdisplays.server.ownername=Owner name: %s
|
||||||
webdisplays.server.owneruuid=Owner UUID:
|
webdisplays.server.owneruuid=Owner UUID:
|
||||||
webdisplays.server.quota=%s/%s used
|
webdisplays.server.quota=%s/%s used
|
||||||
webdisplays.server.urlarg=Missing file name argument
|
webdisplays.server.fnamearg=Missing file name argument
|
||||||
webdisplays.server.nameerr=Invalid file name
|
webdisplays.server.nameerr=Invalid file name
|
||||||
webdisplays.server.urlcopied=Copied URL to clipboard.
|
webdisplays.server.urlcopied=Copied URL to clipboard.
|
||||||
webdisplays.server.notfound=File not found
|
webdisplays.server.notfound=File not found
|
||||||
|
webdisplays.server.upload.uploading=Uploading...
|
||||||
|
webdisplays.server.upload.done=Done
|
||||||
|
webdisplays.server.upload.exists=Error: File exists
|
||||||
|
webdisplays.server.upload.quota=Error: File size exceeds quota
|
||||||
webdisplays.server.help.help=Displays this text
|
webdisplays.server.help.help=Displays this text
|
||||||
webdisplays.server.help.clear=Clears the screen
|
webdisplays.server.help.clear=Clears the screen
|
||||||
webdisplays.server.help.exit=Leaves this console
|
webdisplays.server.help.exit=Leaves this console
|
||||||
|
|
@ -135,3 +139,4 @@ webdisplays.server.help.quota=Displays the storage quota
|
||||||
webdisplays.server.help.ls=Lists the files on this server
|
webdisplays.server.help.ls=Lists the files on this server
|
||||||
webdisplays.server.help.url=Copies a file URL into your clipboard
|
webdisplays.server.help.url=Copies a file URL into your clipboard
|
||||||
webdisplays.server.help.upload=Opens the upload wizard
|
webdisplays.server.help.upload=Opens the upload wizard
|
||||||
|
webdisplays.server.help.rm=Deletes a file
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
{
|
{
|
||||||
"type": "minecraft:crafting_shaped",
|
"type": "minecraft:crafting_shaped",
|
||||||
"pattern": [
|
"pattern": [
|
||||||
"GGG",
|
"PG"
|
||||||
"GSG",
|
|
||||||
"GGG"
|
|
||||||
],
|
],
|
||||||
"key": {
|
"key": {
|
||||||
"G": {
|
"G": {
|
||||||
"item": "minecraft:dye",
|
"item": "minecraft:dye",
|
||||||
"data": 8
|
"data": 8
|
||||||
},
|
},
|
||||||
"S": {
|
"P": {
|
||||||
"item": "webdisplays:screen"
|
"item": "webdisplays:craftcomp",
|
||||||
|
"data": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"result": {
|
"result": {
|
||||||
|
|
|
||||||
20
src/main/resources/assets/webdisplays/recipes/server.json
Normal file
20
src/main/resources/assets/webdisplays/recipes/server.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"pattern": [
|
||||||
|
"PG"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"G": {
|
||||||
|
"item": "minecraft:dye",
|
||||||
|
"data": 2
|
||||||
|
},
|
||||||
|
"P": {
|
||||||
|
"item": "webdisplays:craftcomp",
|
||||||
|
"data": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "webdisplays:peripheral",
|
||||||
|
"data": 11
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user