mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 05:30:06 +08:00
implement speedtest ui
This commit is contained in:
parent
da859cb26f
commit
bd1b1b1635
@ -914,12 +914,15 @@ func (x *IsPrivilegedResponse) GetHasPrivilege() bool {
|
||||
}
|
||||
|
||||
type SpeedTestRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
|
||||
OutboundTags []string `protobuf:"bytes,2,rep,name=outbound_tags,json=outboundTags,proto3" json:"outbound_tags,omitempty"`
|
||||
TestCurrent bool `protobuf:"varint,3,opt,name=test_current,json=testCurrent,proto3" json:"test_current,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
|
||||
OutboundTags []string `protobuf:"bytes,2,rep,name=outbound_tags,json=outboundTags,proto3" json:"outbound_tags,omitempty"`
|
||||
TestCurrent bool `protobuf:"varint,3,opt,name=test_current,json=testCurrent,proto3" json:"test_current,omitempty"`
|
||||
UseDefaultOutbound bool `protobuf:"varint,4,opt,name=use_default_outbound,json=useDefaultOutbound,proto3" json:"use_default_outbound,omitempty"`
|
||||
TestDownload bool `protobuf:"varint,5,opt,name=test_download,json=testDownload,proto3" json:"test_download,omitempty"`
|
||||
TestUpload bool `protobuf:"varint,6,opt,name=test_upload,json=testUpload,proto3" json:"test_upload,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SpeedTestRequest) Reset() {
|
||||
@ -973,6 +976,27 @@ func (x *SpeedTestRequest) GetTestCurrent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SpeedTestRequest) GetUseDefaultOutbound() bool {
|
||||
if x != nil {
|
||||
return x.UseDefaultOutbound
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SpeedTestRequest) GetTestDownload() bool {
|
||||
if x != nil {
|
||||
return x.TestDownload
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SpeedTestRequest) GetTestUpload() bool {
|
||||
if x != nil {
|
||||
return x.TestUpload
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type SpeedTestResult struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
DlSpeed string `protobuf:"bytes,1,opt,name=dl_speed,json=dlSpeed,proto3" json:"dl_speed,omitempty"`
|
||||
@ -1259,105 +1283,113 @@ var file_libcore_proto_rawDesc = string([]byte{
|
||||
0x14, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69,
|
||||
0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x68, 0x61,
|
||||
0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x22, 0x72, 0x0a, 0x10, 0x53, 0x70,
|
||||
0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f,
|
||||
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74,
|
||||
0x65, 0x73, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x22, 0xe2,
|
||||
0x01, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6c, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x19, 0x0a,
|
||||
0x08, 0x75, 0x6c, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x75, 0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65,
|
||||
0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e,
|
||||
0x63, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74,
|
||||
0x61, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x22, 0x47, 0x0a, 0x11, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73,
|
||||
0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x16,
|
||||
0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
|
||||
0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72,
|
||||
0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73,
|
||||
0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x32, 0xfa, 0x07, 0x0a, 0x0e, 0x4c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x45, 0x78,
|
||||
0x69, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70,
|
||||
0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61,
|
||||
0x72, 0x74, 0x12, 0x16, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61,
|
||||
0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2d,
|
||||
0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a,
|
||||
0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x6c,
|
||||
0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74,
|
||||
0x12, 0x10, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x65, 0x73,
|
||||
0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45,
|
||||
0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x38, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72,
|
||||
0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x12, 0x42, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f,
|
||||
0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f,
|
||||
0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a,
|
||||
0x0a, 0x0e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12,
|
||||
0x21, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
|
||||
0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70,
|
||||
0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x4e, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
|
||||
0x65, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x23, 0x2e,
|
||||
0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47,
|
||||
0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70,
|
||||
0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73,
|
||||
0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45,
|
||||
0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x49, 0x73, 0x50, 0x72,
|
||||
0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67,
|
||||
0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x70,
|
||||
0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72,
|
||||
0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65,
|
||||
0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44,
|
||||
0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74,
|
||||
0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75,
|
||||
0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x42, 0x11, 0x5a, 0x0f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x10, 0x53,
|
||||
0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x30, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6f,
|
||||
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x75,
|
||||
0x73, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e,
|
||||
0x64, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x44, 0x6f,
|
||||
0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75,
|
||||
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x74, 0x65, 0x73,
|
||||
0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xe2, 0x01, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65,
|
||||
0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64,
|
||||
0x6c, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64,
|
||||
0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x6c, 0x5f, 0x73, 0x70, 0x65,
|
||||
0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x6c, 0x53, 0x70, 0x65, 0x65,
|
||||
0x64, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6f,
|
||||
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x47, 0x0a, 0x11,
|
||||
0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65,
|
||||
0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65,
|
||||
0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70,
|
||||
0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x30, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54,
|
||||
0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67,
|
||||
0x32, 0xfa, 0x07, 0x0a, 0x0e, 0x4c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x45, 0x78, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12,
|
||||
0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65,
|
||||
0x73, 0x70, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72,
|
||||
0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2d, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12,
|
||||
0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72,
|
||||
0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e,
|
||||
0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e,
|
||||
0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73,
|
||||
0x70, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31,
|
||||
0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e,
|
||||
0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73,
|
||||
0x70, 0x12, 0x38, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12,
|
||||
0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65,
|
||||
0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x42, 0x0a, 0x0f, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x11,
|
||||
0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65,
|
||||
0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x46, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12,
|
||||
0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x47, 0x65,
|
||||
0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65,
|
||||
0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54,
|
||||
0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x4e, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74,
|
||||
0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54,
|
||||
0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x40, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x12,
|
||||
0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73,
|
||||
0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e,
|
||||
0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73,
|
||||
0x70, 0x12, 0x40, 0x0a, 0x0c, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65,
|
||||
0x64, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x49,
|
||||
0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74,
|
||||
0x12, 0x19, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64,
|
||||
0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69,
|
||||
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6c,
|
||||
0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65,
|
||||
0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x11, 0x5a,
|
||||
0x0f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
|
||||
@ -115,6 +115,9 @@ message SpeedTestRequest {
|
||||
string config = 1;
|
||||
repeated string outbound_tags = 2;
|
||||
bool test_current = 3;
|
||||
bool use_default_outbound = 4;
|
||||
bool test_download = 5;
|
||||
bool test_upload = 6;
|
||||
}
|
||||
|
||||
message SpeedTestResult {
|
||||
|
||||
@ -5,6 +5,7 @@ go 1.23.0
|
||||
toolchain go1.24.0
|
||||
|
||||
require (
|
||||
github.com/Mahdi-zarei/speedtest-go v1.7.12
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/gofrs/uuid/v5 v5.3.2
|
||||
github.com/oschwald/maxminddb-golang v1.13.1
|
||||
@ -23,7 +24,6 @@ replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0
|
||||
replace github.com/sagernet/sing-dns => github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250419091211-cee3ab2d4492
|
||||
|
||||
require (
|
||||
github.com/Mahdi-zarei/speedtest-go v1.7.11 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/caddyserver/certmagic v0.20.0 // indirect
|
||||
|
||||
@ -2,8 +2,8 @@ github.com/Mahdi-zarei/sing-box v1.3.5-0.20250419091424-318eff0efb34 h1:xhAgBfvZ
|
||||
github.com/Mahdi-zarei/sing-box v1.3.5-0.20250419091424-318eff0efb34/go.mod h1:wMfYe7SB/9L11IuO7r0A5Rh6eoxGsyjoErxeYwqLgXU=
|
||||
github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250419091211-cee3ab2d4492 h1:fLReuPi1fM99oFRERDU96JzEY1YpLh8PmDGEcfnexCY=
|
||||
github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250419091211-cee3ab2d4492/go.mod h1:dweQs54ng2YGzoJfz+F9dGuDNdP5pJ3PLeggnK5VWc8=
|
||||
github.com/Mahdi-zarei/speedtest-go v1.7.11 h1:K/c7qBlJNAYGv6MujDaIKvtb4AH+yPRdssZ1NJMGPFU=
|
||||
github.com/Mahdi-zarei/speedtest-go v1.7.11/go.mod h1:b1H+UBFUnLKH1YquN2xao8d1hokcnDFFhEKDARTzddM=
|
||||
github.com/Mahdi-zarei/speedtest-go v1.7.12 h1:KktFSpobkhIgrOd25e8IpVzVq2enpCDzQQPVtGxWZV4=
|
||||
github.com/Mahdi-zarei/speedtest-go v1.7.12/go.mod h1:b1H+UBFUnLKH1YquN2xao8d1hokcnDFFhEKDARTzddM=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
|
||||
@ -311,6 +311,9 @@ func (s *server) IsPrivileged(ctx context.Context, _ *gen.EmptyReq) (*gen.IsPriv
|
||||
}
|
||||
|
||||
func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen.SpeedTestResponse, error) {
|
||||
if !in.TestDownload && !in.TestUpload {
|
||||
return nil, errors.New("cannot run empty test")
|
||||
}
|
||||
var testInstance *boxbox.Box
|
||||
var cancel context.CancelFunc
|
||||
outboundTags := in.OutboundTags
|
||||
@ -323,8 +326,6 @@ func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen.
|
||||
}}}, nil
|
||||
}
|
||||
testInstance = boxInstance
|
||||
outbound := testInstance.Outbound().Default()
|
||||
outboundTags = []string{outbound.Tag()}
|
||||
} else {
|
||||
testInstance, cancel, err = boxmain.Create([]byte(in.Config))
|
||||
if err != nil {
|
||||
@ -334,7 +335,12 @@ func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen.
|
||||
defer testInstance.Close()
|
||||
}
|
||||
|
||||
results := BatchSpeedTest(testCtx, testInstance, outboundTags)
|
||||
if in.UseDefaultOutbound || in.TestCurrent {
|
||||
outbound := testInstance.Outbound().Default()
|
||||
outboundTags = []string{outbound.Tag()}
|
||||
}
|
||||
|
||||
results := BatchSpeedTest(testCtx, testInstance, outboundTags, in.TestDownload, in.TestUpload)
|
||||
|
||||
res := make([]*gen.SpeedTestResult, 0)
|
||||
for _, data := range results {
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/Mahdi-zarei/speedtest-go/speedtest"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/service"
|
||||
"nekobox_core/internal/boxbox"
|
||||
@ -137,15 +138,20 @@ func urlTest(ctx context.Context, client *http.Client, url string) (time.Duratio
|
||||
|
||||
func getNetDialer(dialer func(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error)) func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||
return dialer(ctx, network, metadata.Socksaddr{Addr: metadata.ParseAddr(address)})
|
||||
return dialer(ctx, network, metadata.ParseSocksaddr(address))
|
||||
}
|
||||
}
|
||||
|
||||
func BatchSpeedTest(ctx context.Context, i *boxbox.Box, outboundTags []string) []*SpeedTestResult {
|
||||
func BatchSpeedTest(ctx context.Context, i *boxbox.Box, outboundTags []string, testDl, testUl bool) []*SpeedTestResult {
|
||||
outbounds := service.FromContext[adapter.OutboundManager](i.Context())
|
||||
results := make([]*SpeedTestResult, 0)
|
||||
|
||||
for _, tag := range outboundTags {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
break
|
||||
default:
|
||||
}
|
||||
outbound, exists := outbounds.Outbound(tag)
|
||||
if !exists {
|
||||
panic("no outbound with tag " + tag + " found")
|
||||
@ -154,19 +160,23 @@ func BatchSpeedTest(ctx context.Context, i *boxbox.Box, outboundTags []string) [
|
||||
res.Tag = tag
|
||||
results = append(results, res)
|
||||
|
||||
insCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
err := speedTestWithDialer(insCtx, getNetDialer(outbound.DialContext), res)
|
||||
cancel()
|
||||
err := speedTestWithDialer(ctx, getNetDialer(outbound.DialContext), res, testDl, testUl)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
fmt.Println("Failed to speedtest with err:", err)
|
||||
}
|
||||
if !testDl {
|
||||
res.DlSpeed = ""
|
||||
}
|
||||
if !testUl {
|
||||
res.UlSpeed = ""
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, network string, address string) (net.Conn, error), res *SpeedTestResult) error {
|
||||
func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, network string, address string) (net.Conn, error), res *SpeedTestResult, testDl, testUl bool) error {
|
||||
clt := speedtest.New(speedtest.WithUserConfig(&speedtest.UserConfig{
|
||||
DialContextFunc: dialer,
|
||||
PingMode: speedtest.HTTP,
|
||||
@ -194,15 +204,19 @@ func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, n
|
||||
|
||||
go func() {
|
||||
defer func() { close(done) }()
|
||||
err = srv[0].DownloadTestContext(ctx)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
return
|
||||
if testDl {
|
||||
err = srv[0].DownloadTestContext(ctx)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
return
|
||||
}
|
||||
}
|
||||
err = srv[0].UploadTestContext(ctx)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
return
|
||||
if testUl {
|
||||
err = srv[0].UploadTestContext(ctx)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@ -218,7 +232,7 @@ func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, n
|
||||
SpTQuerier.storeResult(res)
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
return E.New("test cancelled")
|
||||
case <-ticker.C:
|
||||
res.DlSpeed = speedtest.ByteRate(srv[0].Context.GetEWMADownloadRate()).String()
|
||||
res.UlSpeed = speedtest.ByteRate(srv[0].Context.GetEWMAUploadRate()).String()
|
||||
|
||||
@ -34,6 +34,8 @@ namespace NekoGui {
|
||||
int id = -1;
|
||||
int gid = 0;
|
||||
int latency = 0;
|
||||
QString dl_speed;
|
||||
QString ul_speed;
|
||||
std::shared_ptr<NekoGui_fmt::AbstractBean> bean;
|
||||
std::shared_ptr<NekoGui_traffic::TrafficData> traffic_data = std::make_shared<NekoGui_traffic::TrafficData>("");
|
||||
|
||||
@ -41,7 +43,7 @@ namespace NekoGui {
|
||||
|
||||
ProxyEntity(NekoGui_fmt::AbstractBean *bean, const QString &type_);
|
||||
|
||||
[[nodiscard]] QString DisplayLatency() const;
|
||||
[[nodiscard]] QString DisplayTestResult() const;
|
||||
|
||||
[[nodiscard]] QColor DisplayLatencyColor() const;
|
||||
|
||||
|
||||
@ -33,4 +33,14 @@ namespace GeoAssets {
|
||||
inline QStringList GeoIPURLs = {"https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db", "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/release/geoip.db"};
|
||||
inline QStringList GeoSiteURLs = {"https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db", "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/release/geosite.db"};
|
||||
}
|
||||
|
||||
namespace TestConfig
|
||||
{
|
||||
enum SpeedTestMode
|
||||
{
|
||||
FULL,
|
||||
DL,
|
||||
UL,
|
||||
};
|
||||
}
|
||||
} // namespace NekoGui
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
// DO NOT INCLUDE THIS
|
||||
|
||||
#include "Const.hpp"
|
||||
|
||||
namespace NekoGui {
|
||||
|
||||
class Routing : public JsonStore {
|
||||
@ -80,6 +82,7 @@ namespace NekoGui {
|
||||
QString splitter_state = "";
|
||||
bool enable_stats = true;
|
||||
QString stats_tab = ""; // either connection or log
|
||||
int speed_test_mode = TestConfig::FULL;
|
||||
|
||||
// Subscription
|
||||
QString user_agent = ""; // set at main.cpp
|
||||
|
||||
@ -219,14 +219,18 @@ private:
|
||||
|
||||
static void setup_grpc();
|
||||
|
||||
void speedtest_current_group(const QList<std::shared_ptr<NekoGui::ProxyEntity>>& profiles);
|
||||
void urltest_current_group(const QList<std::shared_ptr<NekoGui::ProxyEntity>>& profiles);
|
||||
|
||||
void stopSpeedTests();
|
||||
void stopTests();
|
||||
|
||||
void RunSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap<QString, int>& tag2entID, int entID = -1);
|
||||
void runURLTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap<QString, int>& tag2entID, int entID = -1);
|
||||
|
||||
void url_test_current();
|
||||
|
||||
void speedtest_current_group(const QList<std::shared_ptr<NekoGui::ProxyEntity>>& profiles);
|
||||
|
||||
void runSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap<QString, int>& tag2entID, int entID = -1);
|
||||
|
||||
static void stop_core_daemon();
|
||||
|
||||
bool set_system_dns(bool set, bool save_set = true);
|
||||
|
||||
@ -602,6 +602,8 @@
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionUrl_Test_Selected"/>
|
||||
<addaction name="menu_resolve_selected"/>
|
||||
<addaction name="actionSpeedtest_Current"/>
|
||||
<addaction name="actionSpeedtest_Selected"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHidden_menu">
|
||||
<property name="title">
|
||||
@ -614,6 +616,7 @@
|
||||
<addaction name="menu_remove_unavailable"/>
|
||||
<addaction name="menu_clear_test_result"/>
|
||||
<addaction name="menu_delete_repeat"/>
|
||||
<addaction name="actionSpeedtest_Group"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuRouting_Menu">
|
||||
<property name="title">
|
||||
@ -1006,6 +1009,21 @@
|
||||
<string>Open Manager</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSpeedtest_Current">
|
||||
<property name="text">
|
||||
<string>Speedtest Current</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSpeedtest_Selected">
|
||||
<property name="text">
|
||||
<string>Speedtest Selected</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSpeedtest_Group">
|
||||
<property name="text">
|
||||
<string>Speedtest Group</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
@ -179,6 +179,44 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Speedtest mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="speedtest_mode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Download + Upload</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Only Download</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Only Upload</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="horizontalWidget_1" native="true">
|
||||
<property name="sizePolicy">
|
||||
|
||||
@ -249,6 +249,8 @@ namespace NekoGui {
|
||||
_add(new configItem("id", &id, itemType::integer));
|
||||
_add(new configItem("gid", &gid, itemType::integer));
|
||||
_add(new configItem("yc", &latency, itemType::integer));
|
||||
_add(new configItem("dl", &dl_speed, itemType::string));
|
||||
_add(new configItem("ul", &ul_speed, itemType::string));
|
||||
_add(new configItem("report", &full_test_report, itemType::string));
|
||||
|
||||
// 可以不关联 bean,只加载 ProxyEntity 的信息
|
||||
@ -260,14 +262,16 @@ namespace NekoGui {
|
||||
}
|
||||
};
|
||||
|
||||
QString ProxyEntity::DisplayLatency() const {
|
||||
QString ProxyEntity::DisplayTestResult() const {
|
||||
QString result;
|
||||
if (latency < 0) {
|
||||
return QObject::tr("Unavailable");
|
||||
result = "Unavailable";
|
||||
} else if (latency > 0) {
|
||||
return UNICODE_LRO + QString("%1 ms").arg(latency);
|
||||
} else {
|
||||
return "";
|
||||
result = UNICODE_LRO + QString("%1 ms").arg(latency);
|
||||
}
|
||||
if (!dl_speed.isEmpty()) result += " ↓" + dl_speed;
|
||||
if (!ul_speed.isEmpty()) result += " ↑" + ul_speed;
|
||||
return result;
|
||||
}
|
||||
|
||||
QColor ProxyEntity::DisplayLatencyColor() const {
|
||||
|
||||
@ -308,6 +308,7 @@ namespace NekoGui {
|
||||
_add(new configItem("proxy_scheme", &proxy_scheme, itemType::string));
|
||||
_add(new configItem("disable_privilege_req", &disable_privilege_req, itemType::boolean));
|
||||
_add(new configItem("enable_tun_routing", &enable_tun_routing, itemType::boolean));
|
||||
_add(new configItem("speed_test_mode", &speed_test_mode, itemType::integer));
|
||||
}
|
||||
|
||||
void DataStore::UpdateStartedId(int id) {
|
||||
|
||||
@ -421,6 +421,24 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
#endif
|
||||
|
||||
connect(ui->menu_server, &QMenu::aboutToShow, this, [=](){
|
||||
if (running)
|
||||
{
|
||||
ui->actionSpeedtest_Current->setEnabled(true);
|
||||
} else
|
||||
{
|
||||
ui->actionSpeedtest_Current->setEnabled(false);
|
||||
}
|
||||
if (auto selected = get_now_selected_list(); selected.empty())
|
||||
{
|
||||
ui->actionSpeedtest_Selected->setEnabled(false);
|
||||
ui->actionUrl_Test_Selected->setEnabled(false);
|
||||
ui->menu_resolve_selected->setEnabled(false);
|
||||
} else
|
||||
{
|
||||
ui->actionSpeedtest_Selected->setEnabled(true);
|
||||
ui->actionUrl_Test_Selected->setEnabled(true);
|
||||
ui->menu_resolve_selected->setEnabled(true);
|
||||
}
|
||||
if (!speedtestRunning.tryLock()) {
|
||||
ui->menu_server->addAction(ui->menu_stop_testing);
|
||||
} else {
|
||||
@ -452,12 +470,27 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
}
|
||||
});
|
||||
connect(ui->actionUrl_Test_Selected, &QAction::triggered, this, [=]() {
|
||||
speedtest_current_group(get_now_selected_list());
|
||||
urltest_current_group(get_now_selected_list());
|
||||
});
|
||||
connect(ui->actionUrl_Test_Group, &QAction::triggered, this, [=]() {
|
||||
urltest_current_group(NekoGui::profileManager->CurrentGroup()->Profiles());
|
||||
});
|
||||
connect(ui->actionSpeedtest_Current, &QAction::triggered, this, [=]()
|
||||
{
|
||||
if (running != nullptr)
|
||||
{
|
||||
speedtest_current_group({running});
|
||||
}
|
||||
});
|
||||
connect(ui->actionSpeedtest_Selected, &QAction::triggered, this, [=]()
|
||||
{
|
||||
speedtest_current_group(get_now_selected_list());
|
||||
});
|
||||
connect(ui->actionSpeedtest_Group, &QAction::triggered, this, [=]()
|
||||
{
|
||||
speedtest_current_group(NekoGui::profileManager->CurrentGroup()->Profiles());
|
||||
});
|
||||
connect(ui->menu_stop_testing, &QAction::triggered, this, [=]() { stopSpeedTests(); });
|
||||
connect(ui->menu_stop_testing, &QAction::triggered, this, [=]() { stopTests(); });
|
||||
//
|
||||
auto set_selected_or_group = [=](int mode) {
|
||||
// 0=group 1=select 2=unknown(menu is hide)
|
||||
@ -561,7 +594,6 @@ void MainWindow::show_group(int gid) {
|
||||
|
||||
ui->tabWidget->widget(groupId2TabIndex(gid))->layout()->addWidget(ui->proxyListTable);
|
||||
|
||||
// 列宽是否可调
|
||||
if (group->manually_column_width) {
|
||||
for (int i = 0; i <= 4; i++) {
|
||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Interactive);
|
||||
@ -1376,7 +1408,7 @@ void MainWindow::refresh_table_item(const int row, const std::shared_ptr<NekoGui
|
||||
if (profile->full_test_report.isEmpty()) {
|
||||
auto color = profile->DisplayLatencyColor();
|
||||
if (color.isValid()) f->setForeground(color);
|
||||
f->setText(profile->DisplayLatency());
|
||||
f->setText(profile->DisplayTestResult());
|
||||
} else {
|
||||
f->setText(profile->full_test_report);
|
||||
}
|
||||
@ -1726,6 +1758,8 @@ void MainWindow::on_menu_scan_qr_triggered() {
|
||||
void MainWindow::on_menu_clear_test_result_triggered() {
|
||||
for (const auto &profile: get_selected_or_group()) {
|
||||
profile->latency = 0;
|
||||
profile->dl_speed.clear();
|
||||
profile->ul_speed.clear();
|
||||
profile->full_test_report = "";
|
||||
profile->Save();
|
||||
}
|
||||
@ -2056,6 +2090,7 @@ void MainWindow::on_tabWidget_customContextMenuRequested(const QPoint &p) {
|
||||
if (NekoGui::profileManager->groups.size() > 1) menu->addAction(deleteAction);
|
||||
if (!group->Profiles().empty()) {
|
||||
menu->addAction(ui->actionUrl_Test_Group);
|
||||
menu->addAction(ui->actionSpeedtest_Group);
|
||||
menu->addAction(ui->menu_resolve_domain);
|
||||
menu->addAction(ui->menu_clear_test_result);
|
||||
menu->addAction(ui->menu_delete_repeat);
|
||||
|
||||
@ -29,7 +29,7 @@ void MainWindow::setup_grpc() {
|
||||
runOnNewThread([=] {NekoGui_traffic::connection_lister->Loop(); });
|
||||
}
|
||||
|
||||
void MainWindow::RunSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap<QString, int>& tag2entID, int entID) {
|
||||
void MainWindow::runURLTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap<QString, int>& tag2entID, int entID) {
|
||||
if (stopSpeedtest.load()) {
|
||||
MW_show_log(tr("Profile test aborted"));
|
||||
return;
|
||||
@ -78,12 +78,12 @@ void MainWindow::RunSpeedTest(const QString& config, bool useDefault, const QStr
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::speedtest_current_group(const QList<std::shared_ptr<NekoGui::ProxyEntity>>& profiles) {
|
||||
void MainWindow::urltest_current_group(const QList<std::shared_ptr<NekoGui::ProxyEntity>>& profiles) {
|
||||
if (profiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!speedtestRunning.tryLock()) {
|
||||
MessageBoxWarning(software_name, tr("The last speed test did not exit completely, please wait. If it persists, please restart the program."));
|
||||
MessageBoxWarning(software_name, tr("The last url test did not exit completely, please wait. If it persists, please restart the program."));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ void MainWindow::speedtest_current_group(const QList<std::shared_ptr<NekoGui::Pr
|
||||
for (const auto &entID: buildObject->fullConfigs.keys()) {
|
||||
auto configStr = buildObject->fullConfigs[entID];
|
||||
auto func = [this, &counter, testCount, configStr, entID]() {
|
||||
MainWindow::RunSpeedTest(configStr, true, {}, {}, entID);
|
||||
MainWindow::runURLTest(configStr, true, {}, {}, entID);
|
||||
counter++;
|
||||
if (counter.load() == testCount) {
|
||||
speedtestRunning.unlock();
|
||||
@ -112,7 +112,7 @@ void MainWindow::speedtest_current_group(const QList<std::shared_ptr<NekoGui::Pr
|
||||
|
||||
if (!buildObject->outboundTags.empty()) {
|
||||
auto func = [this, &buildObject, &counter, testCount]() {
|
||||
MainWindow::RunSpeedTest(QJsonObject2QString(buildObject->coreConfig, false), false, buildObject->outboundTags, buildObject->tag2entID);
|
||||
MainWindow::runURLTest(QJsonObject2QString(buildObject->coreConfig, false), false, buildObject->outboundTags, buildObject->tag2entID);
|
||||
counter++;
|
||||
if (counter.load() == testCount) {
|
||||
speedtestRunning.unlock();
|
||||
@ -126,12 +126,12 @@ void MainWindow::speedtest_current_group(const QList<std::shared_ptr<NekoGui::Pr
|
||||
speedtestRunning.unlock();
|
||||
runOnUiThread([=]{
|
||||
refresh_proxy_list();
|
||||
MW_show_log(tr("Speedtest finished!"));
|
||||
MW_show_log(tr("URL test finished!"));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::stopSpeedTests() {
|
||||
void MainWindow::stopTests() {
|
||||
stopSpeedtest.store(true);
|
||||
bool ok;
|
||||
defaultClient->StopTests(&ok);
|
||||
@ -170,6 +170,96 @@ void MainWindow::url_test_current() {
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::speedtest_current_group(const QList<std::shared_ptr<NekoGui::ProxyEntity>>& profiles)
|
||||
{
|
||||
if (profiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!speedtestRunning.tryLock()) {
|
||||
MessageBoxWarning(software_name, tr("The last speed test did not exit completely, please wait. If it persists, please restart the program."));
|
||||
return;
|
||||
}
|
||||
|
||||
runOnNewThread([this, profiles]() {
|
||||
auto buildObject = NekoGui::BuildTestConfig(profiles);
|
||||
if (!buildObject->error.isEmpty()) {
|
||||
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
||||
speedtestRunning.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
stopSpeedtest.store(false);
|
||||
for (const auto &entID: buildObject->fullConfigs.keys()) {
|
||||
auto configStr = buildObject->fullConfigs[entID];
|
||||
runSpeedTest(configStr, true, {}, {}, entID);
|
||||
}
|
||||
|
||||
if (!buildObject->outboundTags.empty()) {
|
||||
runSpeedTest(QJsonObject2QString(buildObject->coreConfig, false), false, buildObject->outboundTags, buildObject->tag2entID);
|
||||
}
|
||||
|
||||
speedtestRunning.unlock();
|
||||
runOnUiThread([=]{
|
||||
refresh_proxy_list();
|
||||
MW_show_log(tr("Speedtest finished!"));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::runSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap<QString, int>& tag2entID, int entID)
|
||||
{
|
||||
if (stopSpeedtest.load()) {
|
||||
MW_show_log(tr("Profile speed test aborted"));
|
||||
return;
|
||||
}
|
||||
|
||||
libcore::SpeedTestRequest req;
|
||||
auto speedtestConf = NekoGui::dataStore->speed_test_mode;
|
||||
for (const auto &item: outboundTags) {
|
||||
req.add_outbound_tags(item.toStdString());
|
||||
}
|
||||
req.set_config(config.toStdString());
|
||||
req.set_use_default_outbound(useDefault);
|
||||
req.set_test_download(speedtestConf == NekoGui::TestConfig::FULL || speedtestConf == NekoGui::TestConfig::DL);
|
||||
req.set_test_upload(speedtestConf == NekoGui::TestConfig::FULL || speedtestConf == NekoGui::TestConfig::UL);
|
||||
|
||||
bool rpcOK;
|
||||
auto result = defaultClient->SpeedTest(&rpcOK, req);
|
||||
//
|
||||
if (!rpcOK) return;
|
||||
|
||||
for (const auto &res: result.results()) {
|
||||
if (!tag2entID.empty()) {
|
||||
entID = tag2entID.count(QString(res.outbound_tag().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag().c_str())];
|
||||
}
|
||||
if (entID == -1) {
|
||||
MW_show_log(tr("Something is very wrong, the subject ent cannot be found!"));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto ent = NekoGui::profileManager->GetProfile(entID);
|
||||
if (ent == nullptr) {
|
||||
MW_show_log(tr("Profile manager data is corrupted, try again."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res.error().empty()) {
|
||||
ent->dl_speed = res.dl_speed().c_str();
|
||||
ent->ul_speed = res.ul_speed().c_str();
|
||||
if (ent->latency <= 0 && res.latency() > 0) ent->latency = res.latency();
|
||||
} else {
|
||||
if (QString(res.error().c_str()).contains("test aborted") ||
|
||||
QString(res.error().c_str()).contains("context canceled")) ent->dl_speed = "", ent->ul_speed = "";
|
||||
else {
|
||||
ent->dl_speed = "N/A";
|
||||
ent->ul_speed = "N/A";
|
||||
MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error().c_str()));
|
||||
}
|
||||
}
|
||||
ent->Save();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::stop_core_daemon() {
|
||||
NekoGui_rpc::defaultClient->Exit();
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ void ProxyItem::refresh_data() {
|
||||
ui->name->setText(ent->bean->DisplayName());
|
||||
ui->address->setText(ent->bean->DisplayAddress());
|
||||
ui->traffic->setText(ent->traffic_data->DisplayTraffic());
|
||||
ui->test_result->setText(ent->DisplayLatency());
|
||||
ui->test_result->setText(ent->DisplayTestResult());
|
||||
|
||||
runOnUiThread(
|
||||
[=] {
|
||||
|
||||
@ -33,6 +33,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
D_LOAD_INT(inbound_socks_port)
|
||||
D_LOAD_INT(test_concurrent)
|
||||
D_LOAD_STRING(test_latency_url)
|
||||
ui->speedtest_mode->setCurrentIndex(NekoGui::dataStore->speed_test_mode);
|
||||
|
||||
connect(ui->custom_inbound_edit, &QPushButton::clicked, this, [=] {
|
||||
C_EDIT_JSON_ALLOW_EMPTY(custom_inbound)
|
||||
@ -167,6 +168,7 @@ void DialogBasicSettings::accept() {
|
||||
D_SAVE_INT(test_concurrent)
|
||||
D_SAVE_STRING(test_latency_url)
|
||||
NekoGui::dataStore->proxy_scheme = ui->proxy_scheme->currentText().toLower();
|
||||
NekoGui::dataStore->speed_test_mode = ui->speedtest_mode->currentIndex();
|
||||
|
||||
// Style
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user