YanFrp/src/main/java/top/octopusyan/controller/MainController.java

868 lines
36 KiB
Java

package top.octopusyan.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfoenix.controls.*;
import com.jfoenix.validation.base.ValidatorBase;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import top.octopusyan.base.BaseController;
import top.octopusyan.config.ProxyConfig;
import top.octopusyan.config.ProxyConfig.ProxyServer;
import top.octopusyan.config.ProxyConfig.ProxyType;
import top.octopusyan.config.TextValidate;
import top.octopusyan.http.listener.OnHttpListener;
import top.octopusyan.manager.FrpManager;
import top.octopusyan.manager.ProxyManager;
import top.octopusyan.manager.http.request.ProxySetup;
import top.octopusyan.model.ApplicatonStore;
import top.octopusyan.model.ProxySetupModel;
import top.octopusyan.utils.*;
import java.io.IOException;
import java.util.List;
import java.util.*;
import static top.octopusyan.model.ApplicatonStore.*;
/**
* @author : octopus yan
* @email : octopus_yan@foxmail.com
* @description :
* @create : 2022-4-4 22:32
*/
public class MainController extends BaseController<StackPane> implements Initializable {
public static final String PROXY_LIST_ITEM_CLASS = "proxyListItem";
public static final String PROXY_LIST_ITEM_STOP_CLASS = "proxyListItem-stop";
public static final String PROXY_LIST_ITEM_RUN_CLASS = "proxyListItem-run";
public static final String PROXY_LIST_ITEM_CLOSE_CLASS = "proxyListItem-close";
public static final String PROXY_LIST_ITEM_SELECT_CLASS = "proxyListItem-select";
/* 窗口通用控件 */
public StackPane root;
public JFXButton minimizeBtn, closeBtn;
public Label appVersionLabel;
/* 隧道设置控件 */
public JFXComboBox<String> proxyServerComboBox;
public JFXButton resetProxyBtn;
public JFXTextField proxyNameTextField;
public JFXRadioButton openProxyRBtn, closeProxyRBtn;
public JFXComboBox<String> proxyProtocolComboBox;
public JFXRadioButton serverProviderRBtn, serverVisitorRBtn;
public Label localHostLabel;
public JFXTextField localHostTextField, localPortTextField;
public HBox domainPane;
public JFXTextField domainTextField, domainSuffixTextField;
public JFXButton customizeDomainBtn;
public HBox httpUserPane;
public JFXTextField httpUserTextField;
public HBox httpPwdPane;
public JFXTextField httpPwdTextField;
public HBox p2pRolePane, p2pPwdPane, p2pRoleView, serverNamePane;
public JFXButton copyP2pConfig, importP2pConfig;
public JFXTextField p2pPwdTextField, serverNameTextField;
public JFXButton proxyStatusTip, httpUserTip, proxyTypeTip, p2pPwdTip, serverNameTip;
public HBox proxyStatusPane;
public Label runingLabel;
public Hyperlink domainLink;
public JFXButton copyDomainBtn;
/* 隧道列表控件 */
public JFXListView<Label> proxyListView;
public JFXButton addProxyBtn;
/* 日志帮助面板控件 */
public JFXTabPane tabPane;
public Tab proxyLogPane;
public JFXButton clearLogBtn;
/* 功能控件 */
public JFXButton startProxyBtn, logoutBtn;
/* 自定义属性 */
private ObservableList<Node> children;
private final ProxySetupModel proxySetupModel = new ProxySetupModel(ProxyManager.initProxy(null));
private final BooleanProperty customizeDomain = new SimpleBooleanProperty(false);
private final Map<String, ProxySetup> userProxy = new HashMap<>();
private final Map<String, FrpManager> frpUtilMap = new HashMap<>();
private final ToggleGroup openProxyGroup = new ToggleGroup();
private final ToggleGroup serverRoleGroup = new ToggleGroup();
private final SimpleBooleanProperty setup = new SimpleBooleanProperty(false);
@Override
public boolean dragWindow() {
return true;
}
@Override
public StackPane getRootPanel() {
return root;
}
@NotNull
@Override
public String getRootFxmlPath() {
return "/fxml/main.fxml";
}
@Override
public Label getAppVersionLabel() {
return appVersionLabel;
}
@Override
public Button getClooseBtn() {
return closeBtn;
}
@Override
public Button getMinimizeBtn() {
return minimizeBtn;
}
@Override
public JFXButton getFirstBtn() {
return minimizeBtn;
}
@Override
public void initData() {
// 初始化用户隧道列表
setProxyList(Collections.singletonList(proxySetupModel.get()));
// 重置隧道列表视图
initProxyListView();
// 初始化隧道类型
Arrays.asList(ProxyType.values()).forEach((type) -> proxyProtocolComboBox.getItems().add(type.name()));
// 初始化服务器
Arrays.asList(ProxyServer.values()).forEach((server) -> proxyServerComboBox.getItems().add(server.getServerName()));
// 获取用户隧道列表
ProxyManager.getList(new OnHttpListener<List<ProxySetup>>() {
@Override
public void onSucceed(List<ProxySetup> result) {
Platform.runLater(() -> {
// 如果用户隧道列表不为空
if (result != null && result.size() > 0) {
// 上次关闭时选择的隧道
if (selectProxyName != null)
for (int i = 0; i < result.size(); i++) {
if (result.get(i).getProxy_name().equals(selectProxyName))
selectProxy(i);
selectProxyName = null;
}
// 保存用户隧道信息
for (ProxySetup setup : result) {
userProxy.put(setup.getId().toString(), setup);
}
proxySetupModel.set(result.get(selectProxy()));
// 初始化用户隧道列表
setProxyList(result);
// 重置隧道列表视图
initProxyListView();
}
});
}
@Override
public void onFail(Exception e) {
}
});
/* 数据绑定 */
// 服务器
proxyServerComboBox.valueProperty().bindBidirectional(proxySetupModel.serverProperty());
// 隧道名称
proxyNameTextField.textProperty().bindBidirectional(proxySetupModel.proxyNameProperty());
// 隧道类型
proxyProtocolComboBox.valueProperty().bindBidirectional(proxySetupModel.proxyTypeProperty());
// 内网地址
localHostTextField.textProperty().bindBidirectional(proxySetupModel.localIpProperty());
// 内网端口
localPortTextField.textProperty().bindBidirectional(proxySetupModel.localPortProperty());
// 外网访问子域名
domainTextField.textProperty().bindBidirectional(proxySetupModel.domainProperty());
// 外网访问主域名
domainSuffixTextField.textProperty().bindBidirectional(proxySetupModel.domainSuffixProperty());
// 是否自定义访问域名
customizeDomain.bindBidirectional(proxySetupModel.isCustomizeProperty());
// http访问用户名
httpUserTextField.textProperty().bindBidirectional(proxySetupModel.httpUserProperty());
// http访问密码
httpPwdTextField.textProperty().bindBidirectional(proxySetupModel.httpPwdProperty());
// p2p访问密码
p2pPwdTextField.textProperty().bindBidirectional(proxySetupModel.skProperty());
// p2p访问服务提示
serverNameTextField.textProperty().bindBidirectional(proxySetupModel.serverNameProperty());
// 启动成功提示
proxyStatusPane.visibleProperty().bindBidirectional(proxySetupModel.runningProperty());
}
@Override
public void initViewStyle() {
children = ((Pane) domainPane.getParent()).getChildren();
// 默认隧道协议为http
children.remove(p2pRolePane);
children.remove(p2pPwdPane);
children.remove(serverNamePane);
// 设置列表
proxyListView.getSelectionModel().select(0);
// 启用链接
openProxyRBtn.setToggleGroup(openProxyGroup);
closeProxyRBtn.setToggleGroup(openProxyGroup);
openProxyRBtn.setUserData(true);
closeProxyRBtn.setUserData(false);
openProxyRBtn.setSelected(true);
// 点对点服务角色
serverProviderRBtn.setToggleGroup(serverRoleGroup);
serverVisitorRBtn.setToggleGroup(serverRoleGroup);
serverProviderRBtn.setUserData(true);
serverVisitorRBtn.setUserData(false);
serverProviderRBtn.setSelected(true);
// 是否启用
proxySetupModel.statusProperty().addListener((observable, oldValue, newValue) -> {
openProxyRBtn.setSelected(newValue);
closeProxyRBtn.setSelected(!newValue);
closeProxy(!newValue);
});
// 隧道类型监听
proxySetupModel.proxyTypeProperty().addListener((observable, oldValue, newValue) -> {
String newType = StringUtils.lowerCase(newValue);
String port, host;
if (!newType.equals(StringUtils.upperCase(userProxy.get(proxySetupModel.getId()).getProxy_type()))) {
host = "127.0.0.1";
port = ProxyConfig.getTypePort(newType).toString();
} else {
host = proxySetupModel.getLocalIp();
port = proxySetupModel.getLocalPort();
}
// 隧道类型相关控件显示
boolean isHttp = ProxyConfig.isHttp(proxySetupModel);
boolean isP2p = ProxyConfig.isP2p(proxySetupModel);
if (isHttp) {
// http / https
children.remove(p2pRolePane);
children.remove(p2pPwdPane);
children.remove(serverNamePane);
if (!children.contains(domainPane)) {
int index = children.size() - 1;
children.add(index, httpPwdPane);
children.add(index, httpUserPane);
children.add(index, domainPane);
}
// 添加验证
ObservableList<ValidatorBase> httpValid = domainTextField.getValidators();
if (!httpValid.contains(TextValidate.DomainRequired)) {
httpValid.add(TextValidate.DomainRequired);// 域名为空检查
httpValid.add(TextValidate.domainFormatValidator(proxySetupModel));// 域名格式检查
httpValid.add(TextValidate.domainLengthValidator(proxySetupModel));// 域名长度检查
httpValid.add(TextValidate.domainAddressValidator(proxySetupModel));// 自定义域名解析检查
}
p2pPwdTextField.getValidators().clear();
// 默认系统分配域名
ProxySetup proxySetup = proxySetupModel.get();
if (proxySetup.getDomain().equals("")) {
proxySetup.setDomain("." + ProxyConfig.getServerPath(proxySetupModel.getServer()));
proxySetupModel.set(proxySetup);
}
} else if (isP2p) {
// stcp / xtcp
children.remove(httpPwdPane);
children.remove(httpUserPane);
children.remove(domainPane);
int index = children.size() - 1;
if (!children.contains(p2pRolePane)) {
children.add(index, p2pPwdPane);
children.add(index - 1, p2pRolePane);
if(proxySetupModel.isProvider != null && !proxySetupModel.isProvider){
children.add(index, serverNamePane);
}
}
Boolean provider = proxySetupModel.isProvider();
importP2pConfig.setVisible(provider != null && !provider);
copyP2pConfig.setVisible(provider == null || provider);
// 添加验证
ObservableList<ValidatorBase> p2pValid = p2pPwdTextField.getValidators();
if (!p2pValid.contains(TextValidate.p2pPwdRequired)) {
p2pValid.add(TextValidate.p2pPwdRequired);
p2pValid.add(TextValidate.p2pServerNameRequired);
}
domainTextField.getValidators().clear();
} else {
// tcp / udp
children.remove(p2pRolePane);
children.remove(p2pPwdPane);
children.remove(serverNamePane);
children.remove(httpPwdPane);
children.remove(httpUserPane);
children.remove(domainPane);
// 验证
p2pPwdTextField.getValidators().clear();
domainTextField.getValidators().clear();
}
// 设置本地端口
localHostTextField.setText(host);
localPortTextField.setText(port);
});
// 服务角色监听
proxySetupModel.serverNameProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
serverProviderRBtn.setSelected(false);
serverVisitorRBtn.setSelected(false);
proxySetupModel.isProvider = null;
} else if (oldValue == null) {
if (proxySetupModel.isProvider == null) {
proxySetupModel.isProvider = proxySetupModel.isProvider();
}
serverProviderRBtn.setSelected(proxySetupModel.isProvider);
serverVisitorRBtn.setSelected(!proxySetupModel.isProvider);
}
});
serverRoleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) return;
proxySetupModel.isProvider = (boolean) newValue.getUserData();
if (proxySetupModel.isProvider) {
localHostLabel.setText("内网服务地址");
localHostTextField.setPromptText("内网服务IP (IPv4)");
localPortTextField.setPromptText("端口");
copyP2pConfig.setVisible(true);
importP2pConfig.setVisible(false);
children.remove(serverNamePane);
proxySetupModel.setServerName("提供者");
} else {
localHostLabel.setText("服务绑定地址");
localHostTextField.setPromptText("服务绑定IP (IPv4)");
localPortTextField.setPromptText("端口");
copyP2pConfig.setVisible(false);
importP2pConfig.setVisible(true);
if (!children.contains(serverNamePane)) children.add(children.size() - 3, serverNamePane);
proxySetupModel.setServerName("");
}
ObservableList<Node> children = p2pRolePane.getChildren();
JFXButton remove = proxySetupModel.isProvider ? importP2pConfig : copyP2pConfig;
JFXButton add = proxySetupModel.isProvider ? copyP2pConfig : importP2pConfig;
if (children.contains(add)) children.add(add);
children.remove(remove);
});
// 隧道名称
proxySetupModel.proxyNameProperty().addListener((observable, oldValue, newValue) -> {
if (proxyListView.getItems().size() > 0)
proxyListView.getItems().get(selectProxy()).setText(newValue);
});
// 运行状态监听
proxySetupModel.runningProperty().addListener((observable, oldValue, newValue) -> {
String startClass = "startProxyBtn";
String stopClass = "stopProxyBtn";
// 启动按钮
startProxyBtn.getStyleClass().remove(startClass);
startProxyBtn.getStyleClass().remove(stopClass);
startProxyBtn.getStyleClass().add(newValue ? stopClass : startClass);
startProxyBtn.setText(newValue ? "停止" : "启动");
// 列表显示
ObservableList<String> styleClass = proxyListView.getItems().get(selectProxy()).getStyleClass();
styleClass.remove(PROXY_LIST_ITEM_RUN_CLASS);
styleClass.remove(PROXY_LIST_ITEM_STOP_CLASS);
styleClass.add(newValue ? PROXY_LIST_ITEM_RUN_CLASS : PROXY_LIST_ITEM_STOP_CLASS);
setDomainLink();
});
// 外网访问地址
customizeDomain.addListener((observable, oldValue, newValue) -> {
AnchorPane parent = (AnchorPane) domainTextField.getParent();
if (newValue) {
// 隐藏系统域名
parent.getChildren().remove(domainSuffixTextField);
domainTextField.promptTextProperty().set("自定义域名");
customizeDomainBtn.setText("系统分配");
} else {
// 显示系统域名
if (!parent.getChildren().contains(domainSuffixTextField))
parent.getChildren().add(domainSuffixTextField);
domainTextField.promptTextProperty().set("自定义子域名 大于3位");
customizeDomainBtn.setText("自定义");
}
});
// 默认展示 "常见问题" 面板
tabPane.getSelectionModel().select(1);
}
/**
* 设置访问链接
*/
private void setDomainLink() {
// 外网访问连接
if (ProxyConfig.isHttp(proxySetupModel)) {
runingLabel.setText("启动成功!立即访问 ");
domainLink.setVisible(true);
copyDomainBtn.setVisible(true);
// http / https
String prefix = proxySetupModel.getProxyType() + "://";
domainLink.textProperty().set(prefix + proxySetupModel.getDomain() + proxySetupModel.getDomainSuffix());
} else if (ProxyConfig.isP2p(proxySetupModel)) {
// stcp / xtcp
runingLabel.setText("启动成功!");
domainLink.setText("");
domainLink.setVisible(false);
copyDomainBtn.setVisible(false);
} else {
// ssh / tcp
domainLink.textProperty().set(ProxyConfig.getServerIP(ProxyConfig.getServerNode(proxySetupModel.getServer())) + ":" + proxySetupModel.getRemotePort());
}
}
@Override
public void initViewAction() {
// 重置
resetProxyBtn.setOnMouseClicked(event -> {
ProxySetup proxySetup = userProxy.get(proxySetupModel.getId());
if (proxySetup != null) {
proxySetup.setRuning(proxySetupModel.isRunning());
proxySetupModel.set(proxySetup);
domainTextField.resetValidation();
}
});
// 日志清理
clearLogBtn.setOnMouseClicked(event -> {
ProxySetup proxySetup = userProxy.get(proxySetupModel.getId());
if (frpUtilMap.get(proxySetup.getId().toString()) != null)
frpUtilMap.get(proxySetup.getId().toString()).clearLog();
});
// 更换服务器地址
proxyServerComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
// 重新设置是否自定义
boolean customize = DomainUtil.isCustomize(proxySetupModel.get());
if (!DomainUtil.isCustomize(proxySetupModel.get(), oldValue) || !customize) {
proxySetupModel.setDomainSuffix("." + ProxyConfig.getServerPath(newValue));
customizeDomain.set(false);
} else {
proxySetupModel.setDomainSuffix("");
// 域名检查
domainTextField.validate();
customizeDomain.set(true);
}
});
// 是否启用
openProxyGroup.selectedToggleProperty().addListener(
(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) -> {
Toggle toggle = openProxyGroup.getSelectedToggle();
if (toggle != null) {
// 设置状态
proxySetupModel.setStatus((Boolean) toggle.getUserData());
}
}
);
// 自定义访问域名
customizeDomainBtn.setOnMouseClicked((event) -> {
// 是否切换为自定义域名
if (!customizeDomain.get()) {
// 用户域名是否自定义
if (!DomainUtil.isCustomize(proxySetupModel.get())) {
proxySetupModel.setDomain("");
} else {
proxySetupModel.setDomain(proxySetupModel.getDomain());
}
proxySetupModel.setDomainSuffix("");
} else {
// 用户域名是否自定义
if (DomainUtil.isCustomize(proxySetupModel.get())) {
proxySetupModel.setDomain("");
proxySetupModel.setDomainSuffix("." + ProxyConfig.getServerPath(proxySetupModel.getServer()));
} else {
proxySetupModel.setDomain(DomainUtil.getCustomize(proxySetupModel.get()));
proxySetupModel.setDomainSuffix(DomainUtil.getSuffix(userProxy.get(proxySetupModel.getId())));
}
}
customizeDomain.set(!customizeDomain.get());
});
// 本地IP检查
localHostTextField.getValidators().add(TextValidate.IpRequired);
localHostTextField.getValidators().add(TextValidate.IpFormat);
localHostTextField.textProperty().addListener((observable, oldValue, newValue) -> localHostTextField.validate());
// 端口检查
localPortTextField.getValidators().add(TextValidate.PortRequired);
localPortTextField.getValidators().add(TextValidate.PortFormat);
localPortTextField.textProperty().addListener((observable, oldValue, newValue) -> localPortTextField.validate());
// 域名检查
setup.addListener((observable, oldValue, newValue) -> {
if (newValue) domainTextField.validate();
if (newValue) p2pPwdTextField.validate();
});
// 复制服务设置
copyP2pConfig.setOnMouseClicked(event -> {
if (!localPortTextField.validate() || !localPortTextField.validate() || !p2pPwdTextField.validate())
return;
ProxySetup setup = proxySetupModel.get();
setup.setServer_name(EncryptionUtil.MD5_16(ApplicatonStore.getAccount() + "_" + setup.getSort()));
JSONObject json = JSON.parseObject(JSON.toJSONString(setup));
try {
String serverConfig = EncryptionUtil.DESencode(json.toJSONString(), EncryptionUtil.getDefaultPassword());
// 设置剪切板
ClipUtil.setClip(FrpManager.serverConfigHeader + serverConfig);
AlertUtil.info("复制成功").show();
} catch (Exception e) {
e.printStackTrace();
}
});
// 导入设置
importP2pConfig.setOnMouseClicked(event -> {
try {
String clipData = ClipUtil.getString();
// 服务设置检验
if (clipData == null || !clipData.contains(FrpManager.serverConfigHeader)) throw new Exception();
// 解密服务设置
clipData = clipData.replace(FrpManager.serverConfigHeader, "");
String jsonStr = EncryptionUtil.DESdecode(clipData, EncryptionUtil.getDefaultPassword());
JSONObject jsonObject = JSON.parseObject(jsonStr);
proxySetupModel.set(jsonObject.toJavaObject(ProxySetup.class));
AlertUtil.info("导入成功").show();
} catch (Exception e) {
AlertUtil.error("导入失败,请重新复制服务设置").show();
}
});
// 添加验证
ObservableList<ValidatorBase> httpValid = domainTextField.getValidators();
httpValid.add(TextValidate.DomainRequired);// 域名为空检查
httpValid.add(TextValidate.domainFormatValidator(proxySetupModel));// 域名格式检查
httpValid.add(TextValidate.domainLengthValidator(proxySetupModel));// 域名长度检查
httpValid.add(TextValidate.domainAddressValidator(proxySetupModel));// 自定义域名解析检查
domainTextField.textProperty().addListener((observable, oldValue, newValue) -> domainTextField.validate());
p2pPwdTextField.textProperty().addListener((observable, oldValue, newValue) -> p2pPwdTextField.validate());
// 访问密码检查
p2pPwdTextField.textProperty().addListener((observable, oldValue, newValue) -> {
if (!p2pPwdTextField.getValidators().contains(TextValidate.p2pPwdRequired)) {
p2pPwdTextField.getValidators().add(TextValidate.p2pPwdRequired); // 访问密码为空检查
p2pPwdTextField.getValidators().add(TextValidate.HttpPwdFormat); // 访问密码格式检查
} else
p2pPwdTextField.validate();
});
// 点击隧道列表
proxyListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
ObservableList<Label> items = proxyListView.getItems();
if (items.size() == 0) return;
for (Label item : items) {
item.getStyleClass().remove(PROXY_LIST_ITEM_SELECT_CLASS);
}
if (newValue != null) {
newValue.getStyleClass().add(PROXY_LIST_ITEM_SELECT_CLASS);
int oldIndex = items.indexOf(oldValue);
int newIndex = items.indexOf(newValue);
// 保存隧道状态
ObservableList<ProxySetup> proxyList = proxyList();
if (oldIndex != -1 && StringUtils.isNotEmpty(proxyList.get(oldIndex).getProxy_name()))
proxyList.set(oldIndex, proxySetupModel.get());
ProxySetup proxySetup = proxyList.get(newIndex);
selectProxy(newIndex);
Platform.runLater(() -> {
setup.set(false);
proxySetupModel.set(proxySetup);
if (proxySetup.getId() != null) {
FrpManager frpManager = frpUtilMap.get(proxySetup.getId().toString());
proxyLogPane.contentProperty().set(frpManager == null ? null : frpManager.getConsole());
}
setup.set(true);
setDomainLink();
});
}
});
// 添加隧道
addProxyBtn.setOnMouseClicked(event -> {
// 获取默认隧道设置加入列表
ObservableList<ProxySetup> proxyList = proxyList();
addProxyList(ProxyManager.initProxy(proxyList.get(proxyList.size() - 1).getSort()));
// 重置隧道列表视图
initProxyListView();
proxyListView.getSelectionModel().select(proxyListView.getItems().size() - 1);
});
// 启动
startProxyBtn.setOnMouseClicked(event -> {
if (proxySetupModel.isRunning())
stopProxy();
else
startProxy();
});
// 链接跳转
domainLink.setOnMouseClicked(event -> getApplication().getHostServices().showDocument(domainLink.getText()));
// 复制外网访问地址
copyDomainBtn.setOnMouseClicked(event -> {
// 设置剪切板
ClipUtil.setClip(domainLink.getText());
// 复制成功提示
AlertUtil.info("复制成功,快去分享给小伙伴吧!").show();
});
// 退出登录
logoutBtn.setOnMouseClicked(event -> {
for (String key : frpUtilMap.keySet()) {
frpUtilMap.get(key).stop();
}
ApplicatonStore.logout();
try {
jumpTo(new LoginController());
} catch (IOException e) {
e.printStackTrace();
}
});
// 隧道类型提示
proxyTypeTip.setOnMouseClicked(event -> {
TooltipUtil util = getTooltipUtil();
if (util.isShowing()) util.hide();
else util.showProxyTypeTip(event);
});
// http访问用户名提示
httpUserTip.setOnMouseClicked(event -> {
TooltipUtil util = getTooltipUtil();
if (util.isShowing()) util.hide();
else util.showHttpUserTip(event);
});
// 隧道启用提示
proxyStatusTip.setOnMouseClicked(event -> {
TooltipUtil util = getTooltipUtil();
if (util.isShowing()) util.hide();
else util.showProxyStatusTip(event);
});
// p2p 访问密码提示
p2pPwdTip.setOnMouseClicked(event -> {
TooltipUtil util = getTooltipUtil();
if (util.isShowing()) util.hide();
else util.showP2pPwdTip(event);
});
// p2p 访问服务提示
serverNameTip.setOnMouseClicked(event -> {
TooltipUtil util = getTooltipUtil();
if (util.isShowing()) util.hide();
else util.showP2pServerName(event);
});
}
/**
* 是否启用当前隧道
*/
private void closeProxy(boolean close) {
if (close && proxySetupModel.isRunning()) stopProxy();
proxyNameTextField.setDisable(close); // 隧道名称
proxyProtocolComboBox.setDisable(close);// 隧道类型
localHostTextField.setDisable(close); // 本地地址
localPortTextField.setDisable(close); // 本地端口
domainTextField.setDisable(close); // 外网子域名
httpUserTextField.setDisable(close); // 外网子域名
httpPwdTextField.setDisable(close); // 外网子域名
startProxyBtn.setDisable(close); // 启动按钮
p2pRoleView.setDisable(close); // p2p角色
p2pPwdTextField.setDisable(close); // p2p访问面板
ObservableList<String> styleClass = proxyListView.getItems().get(selectProxy()).getStyleClass();
styleClass.remove(PROXY_LIST_ITEM_STOP_CLASS);
styleClass.remove(PROXY_LIST_ITEM_RUN_CLASS);
styleClass.remove(PROXY_LIST_ITEM_CLOSE_CLASS);
if (close) {
styleClass.add(PROXY_LIST_ITEM_CLOSE_CLASS);
} else {
styleClass.add(proxySetupModel.isRunning() ? PROXY_LIST_ITEM_RUN_CLASS : PROXY_LIST_ITEM_STOP_CLASS);
}
}
private void initProxyListView() {
ObservableList<ProxySetup> proxyList = proxyList();
for (ProxySetup proxy : proxyList.subList(proxyListView.getItems().size(), proxyList.size())) {
setProxyListView(proxyList.indexOf(proxy), proxy);
}
// 设置选中
proxyListView.getSelectionModel().select(selectProxy());
}
private void setProxyListView(int index, ProxySetup setup) {
ObservableList<Label> items = proxyListView.getItems();
try {
Label label = FXMLLoader.load(getClass().getResource("/fxml/proxyItem.fxml"));
label.textProperty().set(setup.getProxy_name());
ObservableList<String> styleClass = label.getStyleClass();
styleClass.addAll(PROXY_LIST_ITEM_CLASS, setup.isRuning() ? PROXY_LIST_ITEM_RUN_CLASS : PROXY_LIST_ITEM_STOP_CLASS);
if (selectProxy() == index) styleClass.add(PROXY_LIST_ITEM_SELECT_CLASS);
if (index < items.size()) {
items.set(index, label);
} else {
items.add(label);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 启动代理
*/
private void startProxy() {
// http访问用户名密码输入验证
if (httpUserPane.isVisible() && StringUtils.isNotEmpty(httpUserTextField.getText())) {
httpUserTextField.getValidators().add(TextValidate.HttpUserFormat);
httpPwdTextField.getValidators().add(TextValidate.HttpPwdFormat);
} else {
httpUserTextField.getValidators().remove(TextValidate.HttpUserFormat);
httpPwdTextField.getValidators().remove(TextValidate.HttpPwdFormat);
}
// 验证
if (!domainTextField.validate() || !localHostTextField.validate() || !localPortTextField.validate() ||
!httpUserTextField.validate() || !httpPwdTextField.validate()
) return;
// 非 http 隧道系统随机分配远程端口
if (!ProxyConfig.isHttp(proxySetupModel) && !ProxyConfig.isP2p(proxySetupModel)) {
// 远程端口为空
if (StringUtils.isEmpty(proxySetupModel.getRemotePort()))
proxySetupModel.setRemotePort(String.valueOf(ProxyManager.randomPort()));
} else {
proxySetupModel.setRemotePort(null);
}
// 清空非隧道类型属性
clearModel();
// 是否有修改
if (!proxySetupModel.get().equals(userProxy.get(proxySetupModel.getId()))) {
// 添加隧道
ProxyManager.add(new OnHttpListener<ProxySetup>() {
@Override
public void onSucceed(ProxySetup result) {
// 如果添加成功
if (result != null) {
userProxy.put(result.getId().toString(), result);
start(result);
}
}
@Override
public void onFail(Exception e) {
}
}, proxySetupModel.get());
} else {
start(proxySetupModel.get());
}
}
/**
* 清空无效属性
*/
private void clearModel() {
boolean http = ProxyConfig.isHttp(proxySetupModel);
boolean p2p = ProxyConfig.isP2p(proxySetupModel);
if (http) {
proxySetupModel.setSk(null);
proxySetupModel.setServerName(null);
proxySetupModel.setRemotePort("");
} else if (p2p) {
proxySetupModel.setHttpPwd(null);
proxySetupModel.setHttpUser(null);
proxySetupModel.setDomain("");
proxySetupModel.setDomainSuffix("");
proxySetupModel.setRemotePort("");
} else {
// tcp / udp
proxySetupModel.setSk(null);
proxySetupModel.setServerName(null);
proxySetupModel.setHttpPwd(null);
proxySetupModel.setHttpUser(null);
proxySetupModel.setDomain("");
proxySetupModel.setDomainSuffix("");
}
}
private void start(ProxySetup setup) {
// 添加成功,设置运行状态
setup.setRuning(frpUtilMap.containsKey(setup.getId().toString()));
proxySetupModel.set(setup);
// 初始化frputil
FrpManager frpManager;
if ((frpManager = frpUtilMap.get(setup.getId().toString())) == null)
frpUtilMap.put(proxySetupModel.getId(), frpManager = FrpManager.init(proxySetupModel));
// 设置文本域对象
if (proxyLogPane.getContent() == null) proxyLogPane.contentProperty().set(frpManager.getConsole());
// 开始
frpManager.start();
// 显示日志
tabPane.getSelectionModel().select(0);
}
/**
* 暂停代理
*/
private void stopProxy() {
// 关闭CMD
FrpManager frpManager = frpUtilMap.get(proxySetupModel.getId());
if (frpManager != null) frpManager.stop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
}