Compare commits

..

2 Commits

7 changed files with 80 additions and 57 deletions
@@ -8,7 +8,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 注解在方法上以获取对 EmoneyProtocol 的额外操作 * 注解在方法上以获取对 Emoney Protocol 的额外操作
* <p> * <p>
* 目前方法必须是受 spring 管理类下的公共成员方法,且接受参数为单参数 JsonNode. * 目前方法必须是受 spring 管理类下的公共成员方法,且接受参数为单参数 JsonNode.
* <p> * <p>
@@ -21,18 +21,15 @@ import java.lang.annotation.Target;
@Target(METHOD) @Target(METHOD)
public @interface ResponseDecodeExtension { public @interface ResponseDecodeExtension {
/** /**
* 指定的 protocolId * @return 指定的 protocolId
* @return
*/ */
String protocolId(); String protocolId();
/** /**
* inspect 的排序 * @return inspect 的排序
* @return
*/ */
int order() default -1; int order() default -1;
/** /**
* 是否在模拟客户端请求和返回时启用, 默认 true * @return 是否在模拟客户端请求和返回时启用, 默认 true
* @return
*/ */
boolean client() default true; boolean client() default true;
} }
@@ -47,23 +47,31 @@ public class ProxySettingControllerV1 extends UpdateBoolServiceController<ProxyS
return super.getOne(id); return super.getOne(id);
} }
@PostMapping("/save") @PostMapping("/save")
@ResponseBody @ResponseBody
public R<?> save(@RequestBody ProxySetting proxySetting) { public R<?> save(@RequestBody ProxySetting proxySetting) {
return super.save(proxySetting); R<?> result = super.save(proxySetting);
} proxySettingService.clearIpInfoCache();
return result;
@PostMapping("/delete") }
@ResponseBody
public R<?> delete(String id) { @PostMapping("/delete")
return super.delete(id); @ResponseBody
} public R<?> delete(String id) {
R<?> result = super.delete(id);
proxySettingService.clearIpInfoCache();
return result;
}
@Override @Override
protected protected
R<?> updateBool(String id, String field, Boolean value) { R<?> updateBool(String id, String field, Boolean value) {
return super.updateBool(id, field, value); R<?> result = super.updateBool(id, field, value);
} if ("isDefault".equals(field)) {
proxySettingService.clearIpInfoCache();
}
return result;
}
@PostMapping("/batchOp") @PostMapping("/batchOp")
@ResponseBody @ResponseBody
@@ -79,10 +87,12 @@ public class ProxySettingControllerV1 extends UpdateBoolServiceController<ProxyS
// op 为空是删除 // op 为空是删除
throw RException.badRequest("操作类型不能为空"); throw RException.badRequest("操作类型不能为空");
} }
else if (ProxySettingBatchOp.DELETE == op) { else if (ProxySettingBatchOp.DELETE == op) {
return R.judge( R<?> result = R.judge(
proxySettingService.removeBatchByIds(idArray)); proxySettingService.removeBatchByIds(idArray));
} proxySettingService.clearIpInfoCache();
return result;
}
LambdaUpdateWrapper<ProxySetting> uw = new LambdaUpdateWrapper<>(); LambdaUpdateWrapper<ProxySetting> uw = new LambdaUpdateWrapper<>();
uw.in(ProxySetting::getId, idArray); uw.in(ProxySetting::getId, idArray);
@@ -13,12 +13,19 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.annotation.Nonnull; import jakarta.annotation.Nonnull;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import quant.rich.emoney.validator.ProxySettingValid; import quant.rich.emoney.validator.ProxySettingValid;
@Data /**
@Accessors(chain = true) * 平台代理配置。
@NoArgsConstructor * <p>
* SQLite 表 proxy_setting 使用触发器维护默认代理的一致性:新增或更新 is_default = 1
* 时会把其他记录置为非默认;不允许把最后一条默认代理改为非默认,也不允许删除默认代理。
* 这部分约束不在 Java 代码里重复实现,调整表结构或导入数据时需要同步检查触发器。
*/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@TableName(value = "proxy_setting", autoResultMap = true) @TableName(value = "proxy_setting", autoResultMap = true)
@ProxySettingValid @ProxySettingValid
public class ProxySetting { public class ProxySetting {
@@ -30,12 +30,16 @@ import quant.rich.emoney.validator.RequestInfoValid;
/** /**
* 用于配置请求时的请求行为,一般而言,请求头与安卓系统的信息有关(build.prop) * 用于配置请求时的请求行为,一般而言,请求头与安卓系统的信息有关(build.prop)
* 虽然部分请求对应服务器可能不进行审核,但合理的请求头能尽可能模仿真机行为,避免风险 * 虽然部分请求对应服务器可能不进行审核,但合理的请求头能尽可能模仿真机行为,避免风险
* @see DeviceInfoConfig * @see DeviceInfoConfig
* @see AndroidSdkLevelConfig * @see AndroidSdkLevelConfig
* @see ChromeVersionsConfig * @see ChromeVersionsConfig
*/ * <p>
@Data * SQLite 表 request_info 使用触发器维护默认请求配置的一致性:新增或更新 is_default = 1
@EqualsAndHashCode(callSuper=false) * 时会把其他记录置为非默认;不允许把最后一条默认请求配置改为非默认,也不允许删除默认请求配置。
* 这部分约束不在 Java 代码里重复实现,调整表结构或导入数据时需要同步检查触发器。
*/
@Data
@EqualsAndHashCode(callSuper=false)
@Accessors(chain = true) @Accessors(chain = true)
@Slf4j @Slf4j
@RequestInfoValid @RequestInfoValid
@@ -9,11 +9,14 @@ import lombok.Data;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
/** /**
* 益盟策略和策略池 * 益盟策略和策略池
*/ * <p>
@Data * SQLite 表 strategy_and_pool 对 pool_id 设置了 UNIQUE_POOL_ID 唯一约束,并使用
@Accessors(chain=true) * ON CONFLICT REPLACE。重复写入同一 pool_id 时会由 SQLite 替换旧记录。
*/
@Data
@Accessors(chain=true)
@TableName(value="strategy_and_pool") @TableName(value="strategy_and_pool")
@ToString @ToString
public class StrategyAndPool implements Comparable<StrategyAndPool> { public class StrategyAndPool implements Comparable<StrategyAndPool> {
@@ -36,9 +36,13 @@ public class ProxySettingService extends SqliteServiceImpl<ProxySettingMapper, P
} }
public synchronized IpInfo refreshIpThroughProxy() { public synchronized IpInfo refreshIpThroughProxy() {
ipInfo = GeoIPUtil.getIpInfoThroughProxy(getDefaultProxySetting()); ipInfo = GeoIPUtil.getIpInfoThroughProxy(getDefaultProxySetting());
return ipInfo; return ipInfo;
} }
} public void clearIpInfoCache() {
ipInfo = null;
}
}
@@ -18,7 +18,6 @@ import java.net.InetAddress;
import java.net.Proxy; import java.net.Proxy;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
@Slf4j @Slf4j
public class GeoIPUtil { public class GeoIPUtil {
@@ -34,8 +33,7 @@ public class GeoIPUtil {
throw new RuntimeException("IP 地址库初始化失败", e); throw new RuntimeException("IP 地址库初始化失败", e);
} }
} }
@Async
public static IpInfo getIpInfoThroughProxy(ProxySetting proxySetting) { public static IpInfo getIpInfoThroughProxy(ProxySetting proxySetting) {
if (proxySetting == null) { if (proxySetting == null) {
throw new RuntimeException("代理为空"); throw new RuntimeException("代理为空");
@@ -66,7 +64,7 @@ public class GeoIPUtil {
String responseBody = response.body().string(); String responseBody = response.body().string();
log.debug("Response ipv4 from proxy: {}", responseBody.trim()); log.debug("Response ipv4 from proxy: {}", responseBody.trim());
ipInfo.setIp(responseBody); ipInfo.setIp(responseBody);
} catch (IOException e) { } catch (Exception e) {
log.warn("Proxy ipv4 error: {}", e.getMessage()); log.warn("Proxy ipv4 error: {}", e.getMessage());
return IpInfo.EMPTY; return IpInfo.EMPTY;
} }
@@ -81,7 +79,7 @@ public class GeoIPUtil {
String responseBody = response.body().string(); String responseBody = response.body().string();
log.debug("Response ipv6 from proxy: {}", responseBody.trim()); log.debug("Response ipv6 from proxy: {}", responseBody.trim());
ipInfo.setIpv6(responseBody); ipInfo.setIpv6(responseBody);
} catch (IOException e) { } catch (Exception e) {
log.warn("Proxy ipv6 error {}", e.getMessage()); log.warn("Proxy ipv6 error {}", e.getMessage());
} }
return queryIpInfoGeoLite(ipInfo); return queryIpInfoGeoLite(ipInfo);
@@ -104,7 +102,7 @@ public class GeoIPUtil {
if (response.getSubdivisions() != null && !response.getSubdivisions().isEmpty()) { if (response.getSubdivisions() != null && !response.getSubdivisions().isEmpty()) {
// 省 // 省
Subdivision subdivision = response.getSubdivisions().get(0); Subdivision subdivision = response.getSubdivisions().getFirst();
if (subdivision != null) { if (subdivision != null) {
String subdivisionStr = subdivision.getNames().get(LOCALE); String subdivisionStr = subdivision.getNames().get(LOCALE);
ipInfo.setSubdivision(subdivisionStr); ipInfo.setSubdivision(subdivisionStr);
@@ -125,4 +123,4 @@ public class GeoIPUtil {
public static void main(String[] args) { public static void main(String[] args) {
System.out.format("GeoLite2-City %s\r\n", queryIpInfoGeoLite(new IpInfo().setIp("46.3.98.216"))); System.out.format("GeoLite2-City %s\r\n", queryIpInfoGeoLite(new IpInfo().setIp("46.3.98.216")));
} }
} }