GoodCheck - блокчек-скрипт для GoodbyeDPI, Zapret, ByeDPI

индиресно надо буит глянуть чё там за, спасибо!

а тот который оригинальный коньпилилтся тока если делать goos=windows ина выходе экзешник буит естесно :sweat_smile: если делать линух там чёто build files exist хуё-моё пока чт забил болт кароч

А чем Wine или Docker не угодил
Так-же виртулизация (ВиртуалБокс или KVM)

Единственный минус - ресурсы улетают хорошо

PS @Ori ждем от тебя решения )

вайн я делал и оно даж запускается интерактивных опций там не видно поетому я прост жал ентер но кокда начинается непосредственно проверка оно падает в терминал ничё не выплёвывает так что ХЗ, а ети вертуализации мне пока чт лень ёрзать :sweat_smile:

кароч я там попробовал ето дело, там конечн обрезано (а имено нету гудбая и запрета) есть тока байдпи понтсунул сратегии скопировал (ато там пуст было) и кароч оно падает

ну ет ничего хотябы база есть уже с етим можн работать (кому нето))

тогда вероятно было замедление, а сейчас уже полный блок непосредственно ggc серверов.
поэтому блокчек вполне подходит

охуж етот квм я хз и ето типа промышленая виртуализация называется?!, в том же виртуалбоксе ето делается без бэ

Потому что бокс - юзерфрендли (он сам создает некоторое окружение для работы)
А вот квм - нет. (тут все самостоятельно)

Хотя проблема решается мостом

Посимвольная замена

Спойлер
var (
	clusterDecodeArrayA = [...]string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e",
		"f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "-"}
	clusterDecodeArrayB = [...]string{"7", "e", "l", "s", "z", "6", "d", "k", "r", "y", "5", "c", "j", "q", "x",
		"4", "b", "i", "p", "w", "3", "a", "h", "o", "v", "2", "9", "g", "n", "u", "0", "8", "f", "m", "t", "1", "-"}
)

func ConvertClusterToURL(codename string) string {
	decodedCodename := ""
	for _, letter := range codename {
		l := string(letter)
		for i := 0; i < len(clusterDecodeArrayA); i++ {
			if l == clusterDecodeArrayA[i] {
				decodedCodename = decodedCodename + clusterDecodeArrayB[i]
				break
			}
		}
	}
	decodedCodename = "https://rr1---sn-" + decodedCodename + ".googlevideo.com"
	return decodedCodename
}

Я даже хз с чего начать, так что вряд ли.

Судя по скрину, в винде ответ курла возвращается без кавычек, а в линухе - с кавычками. И сколько там подобных “подводных камней”? Я на винде и то все баги пофиксить не могу, куда мне ещё и линукс :face_exhaling:

Отдохни …
В кровати усни
Завтра встанешь
И жопа от РКН

сума сойти, нано технолоджи :sweat_smile:

штош ну ладн как нибудь переживу :smiling_face_with_tear:

Ну что же с ciadpi протестил вроде как теперь для него работает.

Релевантный патч на предыдущий пост
diff --git a/utils/utils_unix.go b/utils/utils_unix.go
index e141ddf..817a78f 100644
--- a/utils/utils_unix.go
+++ b/utils/utils_unix.go
@@ -100,7 +100,49 @@ func TaskKill(tasks ...string) error {
 	return nil
 }
 
+func splitArgsWithSpaces(args []string) []string {
+	for i := 0; i < len(args); i++ {
+		if !strings.Contains(args[i], " ") {
+			continue
+		}
+
+		splitArgs := strings.Split(args[i], " ")
+
+		args = append(args[:i], append(splitArgs, args[i+1:]...)...)
+
+		i += len(splitArgs) - 1
+	}
+
+	return args
+}
+
+func trimQuotes(args []string) {
+	for i := 0; i < len(args); i++ {
+		if !strings.Contains(args[i], `"`) { continue }
+		args[i] = strings.Trim(args[i], `" `)
+	}
+}
+
+func replaceNULWithDevNull(args []string) {
+	for i := 0; i < len(args); i++ {
+		if args[i] != "NUL" { continue }
+		args[i] = "/dev/null"
+	}
+}
+
 func BuildCmd(prog string, args []string) *exec.Cmd {
+	// Handle "-o NUL" passed as single argument
+	args = splitArgsWithSpaces(args)
+	// Trim quotes from args cause linux handle raw args fine
+	trimQuotes(args)
+	// Replace pathetic NUL with proper /dev/null
+	replaceNULWithDevNull(args)
+
+	if !path.IsAbs(prog) {
+		wd, _ := os.Getwd()
+		prog = path.Join(wd, prog)
+	}
+
 	exe := exec.Command(prog, args...)
 	return exe
 }

Фулл для удобства.
GoodCheckGoGo_0.8.0.7z (91.3 KB)

Передача аргументов, менеджмент процессами, разница в использовании запрета т.к. nfqws немного другой в плане флагов и перехвата трафика.

Сейчас для ByeDPI должно работать но это самое простое потому что ему ничего не нужно в отличие от запрета для которого надо настраивать маркировку пакетов в nfqueue через файервол чем на линуксе занимаются sh скрипты bol-vanа поднимающие правила из /opt/zapret/config и других.

goodbyedpi на сколько я помню вообще не работает под линуксом нативно так что его пока вычёркиваем.

Очередное доказательство, что портирование гудчека того не стоит. Кому надо - используйте запретовский блокчек. Или ищите как в виртуалке запустить. Или элементарно запустите винду с флешки.

Мне goodcheck чисто для byedpi нужен на телефон стратегии подбирать ну и у zapretа хотя бы по сайтам было бы неплохо распараллелить пока bol-van не добрался до этого в своём блокчеке.

Не если есть такая же утилита хотя бы для byedpi с активной разработкой/поддержкой то скажите мне и я отстану. В противном случае я выступаю за адаптацию.

Проблема в том что часть с проверкой условий через curl, логику прохода стратегий, тестинг, парсинг я переписывать желанием не горю ибо она в любом случае получится общая для всех платформ. Я не фанат плодить миллион утилит поэтому считаю глобально адаптация aka портирование определённо того стоит.

В случае zapret с файерволом можно просто дёргать скрипты bol-vanа выборочно. Они у него там добротно структурирированы. Так что всё сводится к поиску нужных bash функций что позволяет не сильно думать над реализацией.

Смысла правда наверное реально мало т.к. всё как ты и сказал решается виртуализацией. Больше принципиальный вопрос.

Я к слову лоханулся надо было на копии слайса модифицировать аргументы

Патч
diff --git a/utils/utils_unix.go b/utils/utils_unix.go
index 817a78f..9e01c6a 100644
--- a/utils/utils_unix.go
+++ b/utils/utils_unix.go
@@ -131,19 +131,22 @@ func replaceNULWithDevNull(args []string) {
 }
 
 func BuildCmd(prog string, args []string) *exec.Cmd {
+	tmp := make([]string, len(args))
+	copy(tmp, args)
+
 	// Handle "-o NUL" passed as single argument
-	args = splitArgsWithSpaces(args)
+	tmp = splitArgsWithSpaces(tmp)
 	// Trim quotes from args cause linux handle raw args fine
-	trimQuotes(args)
+	trimQuotes(tmp)
 	// Replace pathetic NUL with proper /dev/null
-	replaceNULWithDevNull(args)
+	replaceNULWithDevNull(tmp)
 
 	if !path.IsAbs(prog) {
 		wd, _ := os.Getwd()
 		prog = path.Join(wd, prog)
 	}
 
-	exe := exec.Command(prog, args...)
+	exe := exec.Command(prog, tmp...)
 	return exe
 }

Срочный перезалив.
GoodCheckGoGo_0.8.0_byedpi_linux_compatible_rootless.7z (91.3 KB)
GoodCheckGoGo_0.8.0_byedpi_linux_compatible.7z (91.3 KB)

Для nul можно просто использовать os.DevNull, он сам подставляет, в зависимости от ОС.

Хорошая идея. Тогда жду 0.8.1.

Как раз -2 фикса с NUL и разбивка по пробелу будет не нужна если везде заменить “-o NUL” на два аргумента.

[]string{"-o", os.DevNull}

Я просто старался основной код не трогать а чисто на условной компиляции вывезти. Так проще мержить изменения будет. Благо там почти всё зависящее от ОС было и так в utils вынесено.

Если что патч
diff --git a/requestscurl/requestscurl.go b/requestscurl/requestscurl.go
index e46e3a0..932c8f6 100644
--- a/requestscurl/requestscurl.go
+++ b/requestscurl/requestscurl.go
@@ -8,6 +8,7 @@ import (
 	"goodcheckgogo/utils"
 	"log"
 	"net/http"
+	"os"
 	"strconv"
 	"strings"
 )
@@ -15,7 +16,7 @@ import (
 func CheckConnectivityCurl() (bool, error) {
 
 	keys := options.MyOptions.Curl.BasicKeys
-	keys = append(keys, fmt.Sprintf("-m %d", options.MyOptions.ConnTimeout.Value))
+	keys = append(keys, "-m", utils.Int2Str(options.MyOptions.ConnTimeout.Value))
 	if strategy.IPV == 6 {
 		keys = append(keys, "-6")
 	} else {
@@ -27,7 +28,7 @@ func CheckConnectivityCurl() (bool, error) {
 	if options.MyOptions.SkipCertVerify.Value {
 		keys = append(keys, "--insecure")
 	}
-	keys = append(keys, `-w "%{response_code}"`, "-o NUL", options.MyOptions.NetConnTestURL.Value)
+	keys = append(keys, "-w", `"%{response_code}"`, "-o", os.DevNull, options.MyOptions.NetConnTestURL.Value)
 
 	if !options.MyOptions.SkipCertVerify.Value {
 		log.Printf("Making normal request to '%s' (Curl)\n", options.MyOptions.NetConnTestURL.Value)
@@ -61,7 +62,7 @@ func DnsLookupCurl(_resolver string, _addrToResolve string) string {
 
 	keys := options.MyOptions.Curl.BasicKeys
 	//keys = append(keys, fmt.Sprintf("-m %d", options.MyOptions.ConnTimeout.Value))
-	keys = append(keys, "-m 1")
+	keys = append(keys, "-m", "1")
 	if strategy.IPV == 6 {
 		keys = append(keys, "-6")
 	} else {
@@ -71,9 +72,9 @@ func DnsLookupCurl(_resolver string, _addrToResolve string) string {
 		keys = append(keys, "--insecure")
 	}
 	if _resolver == "" {
-		keys = append(keys, `-w "%{remote_ip}"`, "-o NUL", _addrToResolve)
+		keys = append(keys, "-w", `"%{remote_ip}"`, "-o", os.DevNull, _addrToResolve)
 	} else {
-		keys = append(keys, `-w "%{remote_ip}"`, fmt.Sprintf("--doh-url %s", _resolver), "-Z", "-o NUL", _addrToResolve, "-o NUL", "0.0.0.0")
+		keys = append(keys, "-w", `"%{remote_ip}"`, "--doh-url", _resolver, "-Z", "-o", os.DevNull, _addrToResolve, "-o", os.DevNull, "0.0.0.0")
 	}
 
 	cmd := utils.BuildCmd(options.MyOptions.Curl.ExecutableFullPath, keys)
@@ -87,7 +88,7 @@ func DnsLookupCurl(_resolver string, _addrToResolve string) string {
 
 func ExtractClusterCurl(mappingURL string) string {
 	keys := options.MyOptions.Curl.BasicKeys
-	keys = append(keys, fmt.Sprintf("-m %d", options.MyOptions.ConnTimeout.Value))
+	keys = append(keys, "-m", utils.Int2Str(options.MyOptions.ConnTimeout.Value))
 	if options.MyOptions.SkipCertVerify.Value {
 		keys = append(keys, "--insecure")
 	}
@@ -105,14 +106,14 @@ func ExtractClusterCurl(mappingURL string) string {
 
 func FormRequestsKeys(_resolver string, addresses []checklist.Website) []string {
 	keys := options.MyOptions.Curl.BasicKeys
-	keys = append(keys, fmt.Sprintf("-m %d", options.MyOptions.ConnTimeout.Value))
+	keys = append(keys, "-m", utils.Int2Str(options.MyOptions.ConnTimeout.Value))
 	if strategy.IPV == 6 {
 		keys = append(keys, "-6")
 	} else {
 		keys = append(keys, "-4")
 	}
 	if strategy.Proxy != "noproxy" {
-		keys = append(keys, fmt.Sprintf("--proxy %s", strategy.Proxy))
+		keys = append(keys, "--proxy", strategy.Proxy)
 	}
 	if strategy.Protocol == "UDP" {
 		keys = append(keys, "--http3-only")
@@ -123,20 +124,20 @@ func FormRequestsKeys(_resolver string, addresses []checklist.Website) []string
 	// if _resolver != "" {
 	// 	keys = append(keys, fmt.Sprintf("--doh-url %s", _resolver))
 	// }
-	keys = append(keys, `-w "%{urlnum}$%{response_code}@"`)
-	//keys = append(keys, `-w "%{urlnum}$%{response_code}$%{errormsg}@"`)
+	keys = append(keys, "-w", `"%{urlnum}$%{response_code}@"`)
+	//keys = append(keys, "-w", `"%{urlnum}$%{response_code}$%{errormsg}@"`)
 	if len(addresses) > 1 || _resolver != "" {
-		keys = append(keys, "-Z", "--parallel-immediate", "--parallel-max 200")
+		keys = append(keys, "-Z", "--parallel-immediate", "--parallel-max", "200")
 	}
 	for _, addr := range addresses {
 		if strategy.Proxy == "noproxy" {
-			keys = append(keys, addr.Address, "-o NUL", fmt.Sprintf("--resolve %s:443:%s", utils.InsensitiveReplace(addr.Address, "https://", ""), addr.IP))
+			keys = append(keys, addr.Address, "-o", os.DevNull, "--resolve", fmt.Sprintf("%s:443:%s", utils.InsensitiveReplace(addr.Address, "https://", ""), addr.IP))
 		} else {
-			keys = append(keys, addr.Address, "-o NUL")
+			keys = append(keys, addr.Address, "-o", os.DevNull)
 		}
 	}
 	// if _resolver != "" && len(addresses) < 2 {
-	// 	keys = append(keys, "0.0.0.0", "-o NUL")
+	// 	keys = append(keys, "0.0.0.0", "-o", os.DevNull)
 	// }
 	return keys
 }
diff --git a/strategy/strategy.go b/strategy/strategy.go
index fa63703..1fb7986 100644
--- a/strategy/strategy.go
+++ b/strategy/strategy.go
@@ -147,6 +147,16 @@ func ReadStrategies(file string) ([]Strategy, error) {
 	return s, nil
 }
 
+func stratKeysSplitSpace(keys []string) []string {
+	tmp := make([]string, 0, len(keys))
+
+	for _, key := range keys {
+		tmp = append(tmp, strings.Split(key, " ")...)
+	}
+
+	return tmp
+}
+
 func formStrategies() ([]Strategy, error) {
 
 	var strats []Strategy
@@ -184,7 +194,7 @@ func formStrategies() ([]Strategy, error) {
 			key = replacer.Replace(key)
 			processed = append(processed, strings.Split(key, "&")...)
 		}
-		strats[i].Keys = processed
+		strats[i].Keys = stratKeysSplitSpace(processed)
 		for j := len(strats[i].Keys) - 1; j >= 0; j-- {
 			if strats[i].Keys[j] == "empty" {
 				strats[i].Keys = utils.RemoveFromArrayString(strats[i].Keys, j)
diff --git a/utils/utils.go b/utils/utils.go
index 569bf94..edaf398 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -15,6 +15,10 @@ import (
 	"unicode/utf8"
 )
 
+func Int2Str(num int) string {
+	return strconv.FormatInt(int64(num), 10)
+}
+
 func IsCommented(line string, symbol string) bool {
 	if line != "" {
 		return string(line[0]) == symbol

Ну жди :upside_down_face:
Я хз когда у меня будет настроение опять гудчеком заниматься. Я вообще-то не планировал к нему особо возвращаться.

Значит пока и не надо просто пожалуйста не забудь учесть патч выше в новом релизе если всё же решишь вернутся.