Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions assets/bundles/bundle-mdtx.properties
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ settingV2.arcTurretPlaceCheck.name = 炮台放置时显示禁建范围
settingV2.arcTurretPlacementItem.name = 炮台显示不同弹药射程
settingV2.githubMirror.name = GitHub镜像加速(WZ镜像)
settingV2.githubMirror.description = 优化全球服务器列表及Mod浏览器功能
settingV2.githubAcceleration.category = GH加速配置
settingV2.githubAcceleration.enabled.name = 启用GitHub加速
settingV2.githubAcceleration.enabled.description = 代理GitHub请求,支持自动重试
settingV2.githubAcceleration.cache.name = 启用静态资源缓存
settingV2.githubAcceleration.cacheExpire.name = 缓存过期时间
settingV2.githubAcceleration.maxRetries.name = 最大尝试次数
settingV2.githubAcceleration.proxies.name = 镜像站列表
settingV2.replayRecord.name = 多人游戏录像
settingV2.replayRecord.description = 自动录制游玩过程,输出在saves文件夹\n录像文件较大,记得整理
settingV2.maxSchematicSize.name = 最大选择框(蓝图)大小
Expand Down
9 changes: 8 additions & 1 deletion assets/bundles/bundle-mdtx_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ settingV2.arcTurretPlaceCheck.name = Show No-Build Zones When Placing Turrets
settingV2.arcTurretPlacementItem.name = Show Different Ammo Ranges for Turrets
settingV2.githubMirror.name = GitHub Mirror Acceleration (WZ Mirror)
settingV2.githubMirror.description = Optimizes global server list and mod browser functions
settingV2.githubAcceleration.category = GH Acceleration
settingV2.githubAcceleration.enabled.name = Enable GitHub Acceleration
settingV2.githubAcceleration.enabled.description = Proxy GitHub requests with automatic retries
settingV2.githubAcceleration.cache.name = Enable Static Asset Cache
settingV2.githubAcceleration.cacheExpire.name = Cache Expiration
settingV2.githubAcceleration.maxRetries.name = Max Attempts
settingV2.githubAcceleration.proxies.name = Proxy List
settingV2.replayRecord.name = Multiplayer Recording
settingV2.replayRecord.description = Automatically records gameplay, output in saves folder\nRecording files may be large, remember to clean up
settingV2.maxSchematicSize.name = Max Selection (Schematic) Size
Expand Down Expand Up @@ -294,4 +301,4 @@ unit.quell-missile.name = Quell Missile
unit.scathe-missile.name = Scathe Missile
team.neoplastic.name = Neoplastic

# 学术特色翻译(无需翻译其他语言)
# 学术特色翻译(无需翻译其他语言)
178 changes: 173 additions & 5 deletions patches/arc/0001-API-Http.onBeforeRequest.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,146 @@ Date: Fri, 12 Dec 2025 14:49:28 +0800
Subject: [PATCH] API: Http.onBeforeRequest

---
arc-core/src/arc/util/Http.java | 6 ++++++
1 file changed, 6 insertions(+)
arc-core/src/arc/util/Http.java | 102 ++++++++++++++++++++++++++--------------
1 file changed, 67 insertions(+), 35 deletions(-)

diff --git a/arc-core/src/arc/util/Http.java b/arc-core/src/arc/util/Http.java
index 5be2d92ebc01f37351cc60c2b5c6f9296dabbc5b..e15e644138b4e7ea07ad0d3d483fcb8b640a7a00 100644
index 5be2d92ebc01f37351cc60c2b5c6f9296dabbc5b..a6e85108fb7feb7bb143f6dbbd6f2aff9cd4fdb3 100644
--- a/arc-core/src/arc/util/Http.java
+++ b/arc-core/src/arc/util/Http.java
@@ -157,6 +157,8 @@ public class Http{
@@ -54,15 +55,40 @@ public class Http{
public static class HttpResponse{
private final HttpURLConnection connection;
private HttpStatus status;
+ private byte[] cachedResult;

protected HttpResponse(HttpURLConnection connection) throws IOException{
this.connection = connection;
this.status = HttpStatus.byCode(connection.getResponseCode());
}

+ protected HttpResponse(HttpStatus status, byte[] result){
+ this.connection = null;
+ this.status = status;
+ this.cachedResult = result == null ? Streams.emptyBytes : result;
+ }
+
+ public static HttpResponse ofBytes(int statusCode, byte[] result){
+ return new HttpResponse(HttpStatus.byCode(statusCode), result);
+ }
/** @return the length of received content in bytes as a long. May throw an exception (?) */
public long getContentLength(){
- return connection.getContentLength();
+ if(cachedResult != null) return cachedResult.length;
+ return connection == null ? 0 : connection.getContentLength();
}

/**
@@ -74,20 +112,7 @@ public class Http{
* timeout is specified when creating the HTTP request, with {@link HttpRequest#timeout(int)}
*/
public byte[] getResult(){
- InputStream input = getResultAsStream();
-
- // If the response does not contain any content, input will be null.
- if(input == null){
- return Streams.emptyBytes;
- }
-
- try{
- return Streams.copyBytes(input, connection.getContentLength());
- }catch(IOException e){
- return Streams.emptyBytes;
- }finally{
- Streams.close(input);
- }
+ if(cachedResult != null) return cachedResult;
+ if(connection == null) return cachedResult = Streams.emptyBytes;
+
+ InputStream input = getResultAsStream();
+
+ // If the response does not contain any content, input will be null.
+ if(input == null){
+ return cachedResult = Streams.emptyBytes;
+ }
+
+ try{
+ return cachedResult = Streams.copyBytes(input, connection.getContentLength());
+ }catch(IOException e){
+ return cachedResult = Streams.emptyBytes;
+ }finally{
+ Streams.close(input);
+ }
}

/**
@@ -99,20 +124,10 @@ public class Http{
* timeout is specified when creating the HTTP request, with {@link HttpRequest#timeout(int)}
*/
public String getResultAsString(){
- InputStream input = getResultAsStream();
-
- // If the response does not contain any content, input will be null.
- if(input == null){
- return "";
- }
-
- try{
- return Streams.copyString(input, connection.getContentLength());
- }catch(IOException e){
- return "";
- }finally{
- Streams.close(input);
- }
+ if(cachedResult != null) return new String(cachedResult);
+ if(connection == null) return "";
+ InputStream input = getResultAsStream();
+ if(input == null) return "";
+ try{
+ return Streams.copyString(input, connection.getContentLength());
+ }catch(IOException e){
+ return "";
+ }finally{
+ Streams.close(input);
+ }
}

/**
@@ -122,11 +134,11 @@ public class Http{
* @return An {@link InputStream} with the {@link HttpResponse} data.
*/
public InputStream getResultAsStream(){
- try{
- return connection.getInputStream();
- }catch(IOException e){
- return connection.getErrorStream();
- }
+ if(cachedResult != null) return new ByteArrayInputStream(cachedResult);
+ try{
+ return connection.getInputStream();
+ }catch(IOException e){
+ return connection.getErrorStream();
+ }
}

/** @return the {@link HttpStatus} containing the statusCode of the HTTP response. */
@@ -136,6 +144,7 @@ public class Http{

/** @return the value of the header with the given name as a {@link String}, or null if the header is not set. */
public String getHeader(String name){
+ if(connection == null) return null;
return connection.getHeaderField(name);
}

@@ -144,6 +153,7 @@ public class Http{
* represent the corresponding header values.
*/
public ObjectMap<String, Seq<String>> getHeaders(){
+ if(connection == null) return new ObjectMap<>();
//convert between the struct types
ObjectMap<String, Seq<String>> out = new ObjectMap<>();
Map<String, List<String>> fields = connection.getHeaderFields();
@@ -157,10 +167,16 @@ public class Http{

}

Expand All @@ -20,14 +152,50 @@ index 5be2d92ebc01f37351cc60c2b5c6f9296dabbc5b..e15e644138b4e7ea07ad0d3d483fcb8b
public static class HttpRequest{
public HttpMethod method = HttpMethod.GET;
/** The URL to send this request to.*/
@@ -247,6 +249,10 @@ public class Http{
public String url;
+ /** Success callback for this request; set by submit/block. */
+ public ConsT<HttpResponse, Exception> success;
+ /** If set in onBeforeRequest, this response is returned without network access. */
+ public HttpResponse directResponse;
public ObjectMap<String, String> headers = new ObjectMap<>();
/**The time to wait for the HTTP request to be processed, use 0 to block until it is done. The timeout is used for both
* the timeout when establishing TCP connection, and the timeout until the first byte of data is received.*/
@@ -237,6 +253,7 @@ public class Http{

/** Submits this request asynchronously. */
public void submit(ConsT<HttpResponse, Exception> success){
+ this.success = success;
Http.exec.submit(() -> block(success));
}

@@ -247,6 +264,21 @@ public class Http{
return;
}

+ this.success = success;
+
+ if(onBeforeRequest != null){
+ onBeforeRequest.get(this);
+ }
+
+ if(directResponse != null){
+ try{
+ this.success.get(directResponse);
+ }catch(Exception e){
+ errorHandler.get(e);
+ }
+ return;
+ }
+
try{
URL url;

@@ -301,7 +333,7 @@ public class Http{
HttpStatus status = HttpStatus.byCode(code);
errorHandler.get(new HttpStatusException("HTTP request failed with error: " + code + " (" + status + ", URL = " + url + ")", status, new HttpResponse(connection)));
}else{
- success.get(new HttpResponse(connection));
+ this.success.get(new HttpResponse(connection));
}

}finally{
23 changes: 1 addition & 22 deletions src/mindustryX/Hooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import mindustry.mod.*;
import mindustryX.features.*;

import java.net.*;
import java.util.*;

import static mindustry.Vars.ui;
Expand All @@ -22,17 +21,13 @@ public static void beforeInit(){
SettingsV2.INSTANCE.init();
DebugUtil.init();//this is safe, and better at beforeInit,
BindingExt.init();
Http.onBeforeRequest = req -> GithubAcceleration.beforeRequest(req);
Events.on(ClientLoadEvent.class, (e) -> MetricCollector.INSTANCE.onLaunch());
//deprecated Java 8
if(!OS.isAndroid && Strings.parseInt(OS.javaVersion.split("\\.")[0]) < 17){
Log.warn(VarsX.bundle.javaWarnLog(OS.javaVersion));
Events.on(ClientLoadEvent.class, (e) -> ui.showInfo(VarsX.bundle.javaWarnDialog(OS.javaVersion)));
}
try{
Http.onBeforeRequest = Hooks::onHttp;
}catch(NoSuchFieldError e){
Log.warn("Failed to set Http.onBeforeRequest " + e.toString());
}
}

/** invoke after loading, just before `Mod::init` */
Expand All @@ -55,22 +50,6 @@ public void init(){
}
}

@SuppressWarnings("unused")//call before arc.util.Http$HttpRequest.block
public static void onHttp(Http.HttpRequest req){
if(VarsX.githubMirror.get()){
try{
String url = req.url;
String host = new URL(url).getHost();
if(host.contains("github.com") || host.contains("raw.githubusercontent.com")){
url = "https://gh.tinylake.top/" + url;
req.url = url;
}
}catch(Exception e){
//ignore
}
}
}

public static @Nullable String onHandleSendMessage(String message, @Nullable Player sender){
if(message == null) return null;
if(Vars.ui != null){
Expand Down
4 changes: 0 additions & 4 deletions src/mindustryX/VarsX.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,6 @@ object VarsX {
@JvmField
val noPlayerHitBox = CheckPref("noPlayerHitBox")

@JvmField
val githubMirror = CheckPref("githubMirror")

@JvmField
val arcSpecificInfoTable = CheckPref("gameUI.arcSpecificTable").apply {
addFallbackName("arcSpecificTable")
}
Expand Down
Loading