-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
380 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
common/src/main/java/cn/zbx1425/worldcomment/data/network/ImageHost.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package cn.zbx1425.worldcomment.data.network; | ||
|
||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
|
||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.net.http.HttpClient; | ||
import java.net.http.HttpRequest; | ||
import java.net.http.HttpResponse; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Path; | ||
|
||
public class ImageHost { | ||
|
||
private static final HttpClient HTTP_CLIENT = HttpClient.newHttpClient(); | ||
|
||
private static String apiUrl = "https://storage.zbx1425.cn/img-lsky/api/v1/upload"; | ||
private static String token = "1|FcYzmMmcCylQjcWkk4GdRvNUgGlbE5e7Eh752WOQ"; | ||
|
||
public static ThumbImage uploadImage(Path imagePath) throws IOException, InterruptedException { | ||
MimeMultipartData body = MimeMultipartData.newBuilder() | ||
.withCharset(StandardCharsets.UTF_8) | ||
.addFile("file", imagePath, "application/octet-stream") | ||
.addText("strategy_id", "1") | ||
.build(); | ||
HttpRequest request = HttpRequest.newBuilder(URI.create(apiUrl)) | ||
.header("Content-Type", body.getContentType()) | ||
.header("Authorization", "Bearer " + token) | ||
.POST(body.getBodyPublisher()) | ||
.build(); | ||
HttpResponse<String> response = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString()); | ||
if (response.statusCode() != 200) throw new IOException("HTTP response " + response.statusCode()); | ||
JsonObject linkObj = JsonParser.parseString(response.body()).getAsJsonObject() | ||
.get("data").getAsJsonObject().get("links").getAsJsonObject(); | ||
return new ThumbImage(linkObj.get("url").getAsString(), linkObj.get("thumbnail_url").getAsString()); | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
common/src/main/java/cn/zbx1425/worldcomment/data/network/MimeMultipartData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package cn.zbx1425.worldcomment.data.network; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.math.BigInteger; | ||
import java.net.http.HttpRequest; | ||
import java.nio.charset.Charset; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.*; | ||
|
||
public class MimeMultipartData { | ||
|
||
public static class Builder { | ||
|
||
private String boundary; | ||
private Charset charset = StandardCharsets.UTF_8; | ||
private List<MimedFile> files = new ArrayList<MimedFile>(); | ||
private Map<String, String> texts = new LinkedHashMap<>(); | ||
|
||
private Builder() { | ||
this.boundary = new BigInteger(128, new Random()).toString(); | ||
} | ||
|
||
public Builder withCharset(Charset charset) { | ||
this.charset = charset; | ||
return this; | ||
} | ||
|
||
public Builder withBoundary(String boundary) { | ||
this.boundary = boundary; | ||
return this; | ||
} | ||
|
||
public Builder addFile(String name, Path path, String mimeType) { | ||
this.files.add(new MimedFile(name, path, mimeType)); | ||
return this; | ||
} | ||
|
||
public Builder addText(String name, String text) { | ||
texts.put(name, text); | ||
return this; | ||
} | ||
|
||
public MimeMultipartData build() throws IOException { | ||
MimeMultipartData mimeMultipartData = new MimeMultipartData(); | ||
mimeMultipartData.boundary = boundary; | ||
|
||
var newline = "\r\n".getBytes(charset); | ||
var byteArrayOutputStream = new ByteArrayOutputStream(); | ||
for (var f : files) { | ||
byteArrayOutputStream.write(("--" + boundary).getBytes(charset)); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(("Content-Disposition: form-data; name=\"" + f.name + "\"; filename=\"" + f.path.getFileName() + "\"").getBytes(charset)); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(("Content-Type: " + f.mimeType).getBytes(charset)); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(Files.readAllBytes(f.path)); | ||
byteArrayOutputStream.write(newline); | ||
} | ||
for (var entry: texts.entrySet()) { | ||
byteArrayOutputStream.write(("--" + boundary).getBytes(charset)); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"").getBytes(charset)); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(newline); | ||
byteArrayOutputStream.write(entry.getValue().getBytes(charset)); | ||
byteArrayOutputStream.write(newline); | ||
} | ||
byteArrayOutputStream.write(("--" + boundary + "--").getBytes(charset)); | ||
|
||
mimeMultipartData.bodyPublisher = HttpRequest.BodyPublishers.ofByteArray(byteArrayOutputStream.toByteArray()); | ||
return mimeMultipartData; | ||
} | ||
|
||
public class MimedFile { | ||
|
||
public final String name; | ||
public final Path path; | ||
public final String mimeType; | ||
|
||
public MimedFile(String name, Path path, String mimeType) { | ||
this.name = name; | ||
this.path = path; | ||
this.mimeType = mimeType; | ||
} | ||
} | ||
} | ||
|
||
private String boundary; | ||
private HttpRequest.BodyPublisher bodyPublisher; | ||
|
||
private MimeMultipartData() { | ||
} | ||
|
||
public static Builder newBuilder() { | ||
return new Builder(); | ||
} | ||
|
||
public HttpRequest.BodyPublisher getBodyPublisher() throws IOException { | ||
return bodyPublisher; | ||
} | ||
|
||
public String getContentType() { | ||
return "multipart/form-data; boundary=" + boundary; | ||
} | ||
|
||
} |
88 changes: 88 additions & 0 deletions
88
common/src/main/java/cn/zbx1425/worldcomment/data/network/SubmitDispatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package cn.zbx1425.worldcomment.data.network; | ||
|
||
import cn.zbx1425.worldcomment.data.CommentEntry; | ||
import cn.zbx1425.worldcomment.data.Database; | ||
import cn.zbx1425.worldcomment.network.PacketSubmitCommentC2S; | ||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; | ||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; | ||
import net.minecraft.Util; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.client.Screenshot; | ||
import net.minecraft.core.BlockPos; | ||
|
||
import java.io.File; | ||
import java.nio.file.Path; | ||
import java.util.concurrent.Executor; | ||
import java.util.concurrent.Executors; | ||
import java.util.function.Consumer; | ||
|
||
public class SubmitDispatcher { | ||
|
||
private static final Executor NETWORK_EXECUTOR = Executors.newSingleThreadExecutor(); | ||
private static final Long2ObjectMap<SubmitJob> pendingJobs = new Long2ObjectOpenHashMap<>(); | ||
|
||
public static long addJob(CommentEntry comment, Path imagePath, Consumer<Exception> callback) { | ||
synchronized (pendingJobs) { | ||
long jobId = Database.SNOWFLAKE.nextId(); | ||
SubmitJob job = new SubmitJob(comment, imagePath, callback); | ||
pendingJobs.put(jobId, job); | ||
if (imagePath != null) { | ||
NETWORK_EXECUTOR.execute(() -> { | ||
try { | ||
job.setImage(ImageHost.uploadImage(imagePath)); | ||
trySendPackage(jobId); | ||
} catch (Exception ex) { | ||
if (job.callback != null) job.callback.accept(ex); | ||
removeJob(jobId); | ||
} | ||
}); | ||
} | ||
return jobId; | ||
} | ||
} | ||
|
||
public static void placeJobAt(long jobId, BlockPos blockPos) { | ||
synchronized (pendingJobs) { | ||
if (!pendingJobs.containsKey(jobId)) return; | ||
pendingJobs.get(jobId).setLocation(blockPos); | ||
trySendPackage(jobId); | ||
} | ||
} | ||
|
||
public static void removeJob(long jobId) { | ||
synchronized (pendingJobs) { | ||
pendingJobs.remove(jobId); | ||
} | ||
} | ||
|
||
private static void trySendPackage(long jobId) { | ||
SubmitJob job = pendingJobs.get(jobId); | ||
if (job.isReady()) { | ||
PacketSubmitCommentC2S.ClientLogics.send(job.comment); | ||
if (job.callback != null) job.callback.accept(null); | ||
removeJob(jobId); | ||
} | ||
} | ||
|
||
public static void grabScreenshot(Consumer<Path> callback) { | ||
Minecraft.getInstance().execute(() -> { | ||
File targetFile = getAvailableFile(); | ||
Screenshot.grab(Minecraft.getInstance().gameDirectory, targetFile.getName(), | ||
Minecraft.getInstance().getMainRenderTarget(), | ||
ignored -> { | ||
callback.accept(targetFile.toPath()); | ||
}); | ||
}); | ||
} | ||
|
||
private static File getAvailableFile() { | ||
File screenShotDirectory = new File(Minecraft.getInstance().gameDirectory, Screenshot.SCREENSHOT_DIR); | ||
String s = "WorldComment-" + Util.getFilenameFormattedDateTime(); | ||
int i = 1; | ||
File file1; | ||
while ((file1 = new File(screenShotDirectory, s + (i == 1 ? "" : "_" + i) + ".png")).exists()) { | ||
++i; | ||
} | ||
return file1; | ||
} | ||
} |
Oops, something went wrong.