Лайфхаки BAS


  • administrators

    Использовать можно по разному, например выводить аватарку аккаунта прямо в лог. Или создать анимированную превьюшку со своим логотипом :D, как знак качества.


  • administrators

    Ещё html теги можно исопльзовать в описании ресурсов, с такими же ограничениями, как и с log_html()
    Ограничение длины описания 32 767 символов, значит небольшие картинки в base64 можно установить без переноса файлов:

    <img src="data:image/png;base64,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" width="50" height="52" alt="внедренная иконка папки"/>
    

    0_1525191556798_на форум 29.png


    Если картинка большая, можно указать ссылку на файл:

    <img src="C:/test/2/31.jpg" width="100" height="100" alt="моя аватарка"/>
    

    0_1525191884048_на форум 30.png

    Вот проект


  • administrators

    Но лайфхак всё же добавлю в общую копилку.

    Что бы открыть в браузере у пользователя нужный url можно воспользоваться этим методом.

    1. Создаём шаблон вида:
    [InternetShortcut]
    IDList=
    URL=http://www.yandex.ru/
    

    где - http://www.yandex.ru/ - это адрес, который будет открываться при запуске этого файла.

    1. Сохраняем этот файл под любым именем с расширением .url
    2. Запускаем его через Запустить Процесс
      0_1525192828394_на форум 31.png

    Вот тестовый скрипт



  • Спрашивал про кнопку "Выход" в новом интерфейсе у @support`а дал вот такой способ

    CloseApplication() - закрывает БАС из интерфейса
    


  • Цветной лог в новом интерфейсе

    $("#Logs").prepend("<div><span style='color:blue'>Текст</span></div>");
    $("#Logs").prepend("<div><span style='color:blue'>Тест [[NEW_VARIABLE]]</span></div>");
    

    0_1529321257202_Screenshot_3.png



  • запущенная локализация проекта

    VAR_LANG = _K
    


  • Спасибо @support`y выручает всегда когда нужно
    Объяснил и показал как выводит результаты в новом интерфейсе без скачивания
    Я сделал чтоб выводил в спойлер вот html/css/js
    Результаты.txt
    0_1529606682647_1.gif



  • У многих начинающих пользователей возникают трудности с json. А именно с тем, чтобы правильно построить путь к нужному значению. В этом может помочь очень удобный плагин для Notepad++ JSONViewer Да и продвинутым пользователям он поможет сильно с экономить время!0_1530128716932_2018-06-28_015846.png


  • administrators

    Добавлю немного описания, чем же удобен этот плагин для работы с json. В нём можно выбрать нужный элемент, и внизу появится готовый код, который можно вставить в JSON.parse()
    0_1530136182548_2.png



  • This post is deleted!


  • Добавлена информация о TSV файлах (пункт 9).


  • administrators

    Долго думал в какой ветке выложить этот пост, решил, что ему в Лайфхаках будет самое место. Опишу весь процесс, возможно кому нибудь пригодится промежуточный этап.


    Обратились тут ко мне в личку с нестандартным вопросом, можно ли менять количество потоков в зависимости от условий значений ресурсов. (без "вызова функции в несколько потоков")

    {{test_res}} == "хочу два потока" //запускается 2 потока
    или
    {{test_res}} == "хочу пять потоков" //запускается 5 потоков
    

    Я ответил, что так делать нельзя, но это не совсем так :D


    Чтобы запустить скрипт с количеством потоков равном количеству ресурсов, надо в графе "количество потоков" прописать

    RMap("name").length()
    

    где name это имя ресурса.
    Если ресурс "из файла" то количество потоков будет равно количеству строк в файле, если ресурс "из папки" то количеству файлов в папке и тому подобное.


    После получаса извращенных экспериментов с BAS'ом (да простит меня @support)

    10-5 //сработал
    (2+2)*2 //сработал выдал 8 потоков
    a=10;b=5;a-b //не сработал
    2+2; //не сработал
    2+2*2 //сработал, выдал 6 потоков.. может через евал?
    eval(2+2) //сработал! опа! 
    eval(if(10-5 > 1) {2}) //не сработал
    eval(if(10-5 > 0) {10-8}) //тоже не сработал :(
    eval(a=10;b=5;a-b) //не сработал
    eval("a=10;b=5;a-b") //!! сработало !! :D
    eval("if(10-5 > 1) {2}") //Лол! Сработало :)
    eval("(10-5 > 10) ? 2 : 5") //тоже сработало! Прикольно :)) Вот тебе и иф :))
    eval("{{test}} == 'test' ? 2:5") //не сработало :(
    eval({{test}} + "== 'test' ? 2:5") //тоже не сработало :(
    eval('(10-5 > 10) ? 2 : 5') //сработало..
    

    Пришёл к выводу, что надо применять тот же способ работы с ресурсом, что и в коде проекта

    RS("test", false, false)!
    RESOURCE_1 = _result().get()
    log(RESOURCE_1)
    

    В самом начале скрипта прописал получение значения из ресурса и всё заработало:

    RS("test", false, false)!
    RESOURCE_2 = _result().get()
    section(eval("RESOURCE_2 == 'test' ? 2:5") /*eval("RESOURCE_2 == 'test' ? 2:5")*/,1 /*1*/,1 /*1*/,0,function(){
    

    0_1537265715472_1ff864f2-8db6-48c5-b35b-150379c648a2-изображение.png
    0_1537265939090_на форум34.gif
    Вот тестовый скрипт


    Пока печатал пост подумал, что можно через RMap решить эту задачу без правки руками кода проекта.

    Количество потоков:

    eval("RMap('toster').at(0) == 'tost' ? 2:5")
    

    0_1537266871662_на форум35.gif
    Вот скрипт без ручной правки кода.


    Данным способом можно ставить практически любые условия и менять количество потоков в зависимости от них.


  • administrators

    Как подсказал @Denis_krsk можно и без eval() :D

    RMap('toster').at(0) == 'tost' ? 2 : 5
    


  • Возможно совсем для новичков, но все же. Для уменьшения количества итоговых действий в скрипте ( когда все отлажено ), можно пойти таким путем.
    Кликаем для редактирования простого действия(работа с xpath,регулярками,рэндомом,датой и тд) и копируем его id
    0_1538592756687_Screenshot_1.png
    далее переходим сюда
    0_1538591780990_Screenshot_3.png
    нажимаем ctrl+f и вставляем наш id (команда для вставки ctrl+v)
    Видим такой текст
    0_1538592910174_Screenshot_2.png
    нас интересует только все что после section_start и зелёных надписей до section_end
    вставляем этот текст в
    0_1538592021865_Screenshot_6.png
    и таким же образом поступаем с остальными не сложными действиями. Соответсвенно добавляя ВСЕ эти действия в один код.
    Итог : количество (элементарных) действий уменьшилось, читаемость повысилась


  • administrators

    Не скажу, кто именно, но кто то на форуме спросил :D
    0_1540930262180_c213a8fd-bcff-46ae-aa49-01bc2ab81433-изображение.png

    И я начал смотреть разные gui, для себя нашёл очень интересную nwjs, но о ней в следующий раз. А потом вспомнил, что есть более простые решения этой задачи на VBScript.

    Код VBS скрипта :

    result = MsgBox ("Fox is a great forum admin?", vbYesNo, "Yes or No?")
    
    Select Case result
    Case vbYes
        WScript.Echo("yes")
    Case vbNo
        WScript.Echo("no")
    End Select
    

    и код действия "Запустить Процесс":

    @echo off
    @ cscript //Nologo Fox.vbs
    

    0_1540930769732_на форум 7.gif


    0_1540930782118_на форум 8.gif

    Вот тестовый скрипт для наглядности.



  • Расширенный spintax.

    Кроме стандартного БАСовского перебора {1|2|3} может менять текст местами, поддерживает любую вложеность.
    Вставить в экшн "Выполнить код"

    /*Спинтакс 
    {текст 1|текст 2|текст 3} - перебор вариантов
    [текст 1|текст 2|текст 3] - перестановки
    [+разделитель+текст 1|текст 2|текст 3] - перестановки с разделителем
    \{ \} \| [ ] \+ \\ - экранизация спецсимволов
    Поддерживается вложенность команд
    */
    function TextRandomizator_Node($parent) {
    	$parent = (typeof $parent !== 'undefined') ? $parent : null;
    	var $this = this;
    	//$this.$_parent = null;
    	$this.$_str = '';
    	$this.$_type = 'mixing';
    	$this.$_subNodes = [];
    	$this.$_usedKeys_s = [];
    	$this.$_usedKeys_m = [];
    	$this.var_num_m = 0;
    	$this.$pset_arr = [];
    	$this.$_separator = '';
    	$this.$_isSeparator = false;
    	$this.$_parent = $parent;
    	if($parent) {
    		$this.$_parent.$_subNodes.push($this);
    	}
    	function shuffle($arr) {
    		function compareRandom(a, b) {
    			return Math.random() - 0.5;
    		}
    		return $arr.sort(compareRandom);
    	}
    	function sort_arr_arr($arr, $key_arr) {
    		var output = [];
    		for(var $i=0; $i<$key_arr.length; $i++) {
    			output.push($arr[$key_arr[$i]]);
    		}
    		return output;
    	}
    	function array_keys(myObject) {
    		var output = [];
    		for(var key in myObject) {
    			output.push(key);
    		}
    		return output;
    	}
    	function swap($i, $j, $arr) {
    		if($i != $j) {
    			var $temp = $arr[$i];
    			$arr[$i] = $arr[$j];
    			$arr[$j] = $temp;
    		}
    		return $arr;
    	}
    	function reverse_arr($k, $arr) {
    		var $i = 0;
    		var $j = $k;
    		while($i < $j) {
    			$arr = swap($i, $j, $arr);
    			$i++;
    			$j--;
    		}
    		return $arr;
    	}
    
    	function gen_mset($arr, $k) {	
    		if ($k == 0) {
    			$this.$pset_arr.push($arr.slice());
    		} else {
    			for(var $i = 0; $i <= $k; $i++) {
    				gen_pvar($k-1, $arr);
    				if($i < $k) {
    					$arr = swap($i, $k, $arr);
    					$arr = reverse_arr($k - 1, $arr);
    				}
    			}
    		}
    	}
    
    	function next_mset($arr, $n) {
    		var $j = $n - 2;
    		while($j != -1 && $arr[$j] >= $arr[$j + 1]) $j--;
    		if ($j == -1)
    			return false;
    		var $k = $n - 1;
    		while ($arr[$j] >= $arr[$k]) $k--;
    		$arr = swap($j, $k, $arr);
    		var $l = $j + 1, $r = $n - 1;
    		while ($l<$r)
    			$arr = swap($l++, $r--, $arr);
    		return $arr;
    	}
    	
        $this.get_text = function($rand) {
    		$rand = (typeof $rand !== 'undefined') ? $rand : false;
            var $result = '';
            switch ($this.$_type) {
                case 'synonyms':
    				if ($this.$_usedKeys_s.length == 0) {
                        $this.$_usedKeys_s = array_keys($this.$_subNodes);
    				}
    				if($rand == true) {
    					var $random_key = Math.floor(Math.random() * ($this.$_usedKeys_s.length));
    					var $key = $this.$_usedKeys_s[$random_key];
    					$result = $this.$_subNodes[$key].get_text($rand);
    					$this.$_usedKeys_s.splice($random_key, 1);				
    				} else {
    					var $key_s = $this.$_usedKeys_s[0];
    					$result = $this.$_subNodes[$key_s].get_text($rand);
    					$this.$_usedKeys_s.splice(0, 1);
    				}
    				break;
                case 'mixing':
    				var $_subNodes_m = $this.$_subNodes;
    				if($this.$_usedKeys_m.length == 0 && $this.$_subNodes.length > 1) {
    					if($rand == true) {
    						$this.$_subNodes = shuffle($this.$_subNodes);
    					}
    					$_subNodes_m = $this.$_subNodes;
    					$this.$_usedKeys_m = array_keys($this.$_subNodes);
    				}
    				if($this.$_usedKeys_m.length > 1) {
    					$this.$_usedKeys_m = next_mset($this.$_usedKeys_m, $this.$_usedKeys_m.length);
    					if($this.$_usedKeys_m == false) {
    						$this.$_usedKeys_m = array_keys($this.$_subNodes);
    					}
    					$_subNodes_m = sort_arr_arr($this.$_subNodes, $this.$_usedKeys_m);
    				}
                    $_subNodes_m.forEach(function($item, $i, $arr) {
                        if($result) {
                            $result += '' + $this.$_separator;
                        }
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                case 'series':
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                default:
                    $result = $this.$_str;
    		}
    		//$result = $result.trim();
            $result = $result.replace(new RegExp('\\s+', 'g'), ' ');
            $result = $result.replace(' ,', ',');
            $result = $result.replace(' .', '.');
            $result = $result.replace(' !', '!');
            $result = $result.replace(' ?', '?');
            return $result;
        }
    
        $this.num_variant = function() {
            var $result = 1;
            switch ($this.$_type) {
                case 'synonyms':
                    $result = 0;
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += $item.num_variant();
                    });
                    break;
                case 'mixing':
                    for (var $i=2, $kol=$this.$_subNodes.length; $i<=$kol; ++$i) {
                        $result *= $i;
                    }
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
                case 'series':
                   $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
            }
            return $result;
        }
    
        $this.concat = function($str) {
            $str = String($str);
            if ($this.$_isSeparator) {
                $this.$_separator += $str;
                return $this;
            }
            if ('string' == $this.$_type) {
                $this.$_str += $str;
                return $this;
            }
            $currentNode = new TextRandomizator_Node($this);
            $currentNode.set_type('string');
            return $currentNode.concat($str);
        }
    
        $this.set_type = function ($type) {
            switch (String($type)) {
                case 'string':
                    $this.$_type = 'string';
                    break;
                case 'synonyms':
                    $this.$_type = 'synonyms';
                    break;
                case 'series':
                    $this.$_type = 'series';
                    break;
                default:
                    $this.$_type = 'mixing';
            }
        }
    
        $this.get = function($var) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    return $this.$_isSeparator;
                    break;
                case 'parent':
                    return $this.$_parent;
                    break;
                case 'type':
                    return $this.$_type;
                    break;
                default:
                    return null;
            }
        }
    
        $this.set = function($var, $value) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    $this.$_isSeparator = $value;
            }
        }
    }
    
    function TextRandomizator($text) {
    	$text = (typeof $text !== 'undefined') ? $text : '';
    	var $text = String($text);
    	var $match = [];
    	var $this = this;
    	$this.$_tree = null;
    	$this.$_text = $text;
    	$this.$_tree = new TextRandomizator_Node();
    	var regexp_str ='\\\\\\\\|\\\\\[|\\\\\]|\\\\\\{|\\\\\\}|\\\\\\+|\\\\\\||\[\\+|\\+|\\{|\\}|\[|\]|\\||[^\\\\\\+\\{\\}[\]\\|]+';
    	var $regexp = new RegExp(regexp_str, '');
            $currentNode = $this.$_tree;
            $currentNode = new TextRandomizator_Node($currentNode);
            $currentNode.set_type('series');
            $currentNode = $currentNode.concat('');
    		//while(($match = /\\\\|\\[|\\]|\\\{|\\\}|\\\+|\\\||[\+|\+|\{|\}|[|]|\||[^\\\+\{\}[]\|]+/.exec($text)) != null) {
    		while(($match =  $regexp.exec($text)) != null) {
    			switch ($match[0]) {
    				case '\\\\':
    				case '\\':
    					$currentNode = $currentNode.concat('\\');
    					break;
    				case '\\+':
    					$currentNode = $currentNode.concat('+');
    					break;
    				case '\\{':
    					$currentNode = $currentNode.concat('{');
    					break;
    				case '\\}':
    					$currentNode = $currentNode.concat('}');
    					break;
    				case '\[':
    					$currentNode = $currentNode.concat('[');
    					break;
    				case '\]':
    					$currentNode = $currentNode.concat(']');
    					break;
    				case '\\|':
    					$currentNode = $currentNode.concat('|');
    					break;
    				case '[+':
    					if('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set('isSeparator', true);
    					break;
    				case '+':
    					if ($currentNode.get('isSeparator') == true) {
    						$currentNode.set('isSeparator', false);
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('+');
    					}
    					break;
    				case '{':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set_type('synonyms');
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case '}':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'synonyms' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('}');
    					}
    					break;
    				case '[':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case ']':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'mixing' == $is.get('type') && $is.get('parent')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat(']');
    					}
    					break;
    				case '|':
    					var $is = $currentNode.get('parent');
    					if ($is && 'series' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('|');
    					}
    					break;
    				default:
    					$currentNode = $currentNode.concat($match[0]);
    			}
    			$text = $text.substr($match[0].length);
    		}
    		
    	$this.get_text = function($rand) {
    		return $this.$_tree.get_text($rand);
    	}
    
    	$this.num_variant = function() {
    		return $this.$_tree.num_variant();
    	}
    }
    
    var text_data = [[SPINTAX_TEXT]];   // Ваш текст
    var rm_text = new TextRandomizator(text_data);
    var rm_text_random = true;
    VAR_SPINTAX_TEXT = (rm_text.get_text(rm_text_random));
    

    За наводку спасибо @Fox


  • administrators

    @bms-java said in Лайфхаки BAS:

    Расширенный spintax.

    Кроме стандартного БАСовского перебора {1|2|3} может менять текст местами, поддерживает любую вложеность.
    Вставить в экшн "Выполнить код"

    Твой код не работает, а искать почему, мне лень :D.
    Скопировал библиотеку по новой (библиотека взята с сайта http://xbb.uz/randomizator/) и немного подправил код, чтобы не поймать баг в объявлении именованой функции.


    /* Библиотека для обработки текста рандомизатором http://gsgen.ru/ */
    /* Поддерживаемые шаблоны и директивы */
    /*
    {текст 1|текст 2|текст 3} - перебор вариантов
    [текст 1|текст 2|текст 3] - перестановки
    [+разделитель+текст 1|текст 2|текст 3] - перестановки с разделителем
    \{ \} \| [ ] \+ \\ - экранизация спецсимволов
    */
    TextRandomizator_Node = function($parent) {
    	$parent = (typeof $parent !== 'undefined') ? $parent : null;
    	var $this = this;
    	//$this.$_parent = null;
    	$this.$_str = '';
    	$this.$_type = 'mixing';
    	$this.$_subNodes = [];
    	$this.$_usedKeys_s = [];
    	$this.$_usedKeys_m = [];
    	$this.var_num_m = 0;
    	$this.$pset_arr = [];
    	$this.$_separator = '';
    	$this.$_isSeparator = false;
    	$this.$_parent = $parent;
    	if($parent) {
    		$this.$_parent.$_subNodes.push($this);
    	}
    // Перемешать элементы массива в случайном порядке
    	function shuffle($arr) {
    		function compareRandom(a, b) {
    			return Math.random() - 0.5;
    		}
    		return $arr.sort(compareRandom);
    	}
    // Сортировка элементов массива по заданному массиву ключей
    	function sort_arr_arr($arr, $key_arr) {
    		var output = [];
    		for(var $i=0; $i<$key_arr.length; $i++) {
    			output.push($arr[$key_arr[$i]]);
    		}
    		return output;
    	}
    // Получение списка ключей массива	
    	function array_keys(myObject) {
    		var output = [];
    		for(var key in myObject) {
    			output.push(key);
    		}
    		return output;
    	}
    // Поменять местами элементы массива
    	function swap($i, $j, $arr) {
    		if($i != $j) {
    			var $temp = $arr[$i];
    			$arr[$i] = $arr[$j];
    			$arr[$j] = $temp;
    		}
    		return $arr;
    	}
    // Расстановка элементов в обратном порядке от заданной позиции
    	function reverse_arr($k, $arr) {
    		var $i = 0;
    		var $j = $k;
    		while($i < $j) {
    			$arr = swap($i, $j, $arr);
    			$i++;
    			$j--;
    		}
    		return $arr;
    	}
    // Генерация массива с перестановками
    	function gen_mset($arr, $k) {	
    		if ($k == 0) {
    			$this.$pset_arr.push($arr.slice());
    		} else {
    			for(var $i = 0; $i <= $k; $i++) {
    				gen_pvar($k-1, $arr);
    				if($i < $k) {
    					$arr = swap($i, $k, $arr);
    					$arr = reverse_arr($k - 1, $arr);
    				}
    			}
    		}
    	}
    // Генерация следующей перестановки
    	function next_mset($arr, $n) {
    		var $j = $n - 2;
    		while($j != -1 && $arr[$j] >= $arr[$j + 1]) $j--;
    		if ($j == -1)
    			return false; // больше перестановок нет
    		var $k = $n - 1;
    		while ($arr[$j] >= $arr[$k]) $k--;
    		$arr = swap($j, $k, $arr);
    		var $l = $j + 1, $r = $n - 1; // сортируем оставшуюся часть последовательности
    		while ($l<$r)
    			$arr = swap($l++, $r--, $arr);
    		return $arr;
    	}
    	
        $this.get_text = function($rand) {
    		$rand = (typeof $rand !== 'undefined') ? $rand : false;
            var $result = '';
            switch ($this.$_type) {
                case 'synonyms':
    				if ($this.$_usedKeys_s.length == 0) {
                        $this.$_usedKeys_s = array_keys($this.$_subNodes);
    				}
    				if($rand == true) {
    					var $random_key = Math.floor(Math.random() * ($this.$_usedKeys_s.length));
    					var $key = $this.$_usedKeys_s[$random_key];
    					$result = $this.$_subNodes[$key].get_text($rand);
    					$this.$_usedKeys_s.splice($random_key, 1);				
    				} else {
    					var $key_s = $this.$_usedKeys_s[0];
    					$result = $this.$_subNodes[$key_s].get_text($rand);
    					$this.$_usedKeys_s.splice(0, 1);
    				}
    				break;
                case 'mixing':
    				var $_subNodes_m = $this.$_subNodes;
    				if($this.$_usedKeys_m.length == 0 && $this.$_subNodes.length > 1) {
    					if($rand == true) {
    						$this.$_subNodes = shuffle($this.$_subNodes);
    					}
    					$_subNodes_m = $this.$_subNodes;
    					$this.$_usedKeys_m = array_keys($this.$_subNodes);
    				}
    				if($this.$_usedKeys_m.length > 1) {
    					$this.$_usedKeys_m = next_mset($this.$_usedKeys_m, $this.$_usedKeys_m.length);
    					if($this.$_usedKeys_m == false) {
    						$this.$_usedKeys_m = array_keys($this.$_subNodes);
    					}
    					$_subNodes_m = sort_arr_arr($this.$_subNodes, $this.$_usedKeys_m);
    				}
                    $_subNodes_m.forEach(function($item, $i, $arr) {
                        if($result) {
                            $result += '' + $this.$_separator;
                        }
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                case 'series':
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                default:
                    $result = $this.$_str;
    		}
    		//$result = $result.trim();
            $result = $result.replace(new RegExp('\\s+', 'g'), ' ');
            $result = $result.replace(' ,', ',');
            $result = $result.replace(' .', '.');
            $result = $result.replace(' !', '!');
            $result = $result.replace(' ?', '?');
            return $result;
        }
    
        $this.num_variant = function() {
            var $result = 1;
            switch ($this.$_type) {
                case 'synonyms':
                    $result = 0;
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += $item.num_variant();
                    });
                    break;
                case 'mixing':
                    for (var $i=2, $kol=$this.$_subNodes.length; $i<=$kol; ++$i) {
                        $result *= $i;
                    }
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
                case 'series':
                   $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
            }
            return $result;
        }
    
        $this.concat = function($str) {
            $str = String($str);
            if ($this.$_isSeparator) {
                $this.$_separator += $str;
                return $this;
            }
            if ('string' == $this.$_type) {
                $this.$_str += $str;
                return $this;
            }
            $currentNode = new TextRandomizator_Node($this);
            $currentNode.set_type('string');
            return $currentNode.concat($str);
        }
    
        $this.set_type = function ($type) {
            switch (String($type)) {
                case 'string':
                    $this.$_type = 'string';
                    break;
                case 'synonyms':
                    $this.$_type = 'synonyms';
                    break;
                case 'series':
                    $this.$_type = 'series';
                    break;
                default:
                    $this.$_type = 'mixing';
            }
        }
    
        $this.get = function($var) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    return $this.$_isSeparator;
                    break;
                case 'parent':
                    return $this.$_parent;
                    break;
                case 'type':
                    return $this.$_type;
                    break;
                default:
                    return null;
            }
        }
    
        $this.set = function($var, $value) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    $this.$_isSeparator = $value;
            }
        }
    }
    
    TextRandomizator = function($text) {
    	$text = (typeof $text !== 'undefined') ? $text : '';
    	var $text = String($text);
    	var $match = [];
    	var $this = this;
    	$this.$_tree = null;
    	$this.$_text = $text;
    	$this.$_tree = new TextRandomizator_Node();
    	var regexp_str ='\\\\\\\\|\\\\\[|\\\\\]|\\\\\\{|\\\\\\}|\\\\\\+|\\\\\\||\[\\+|\\+|\\{|\\}|\[|\]|\\||[^\\\\\\+\\{\\}[\]\\|]+';
    	var $regexp = new RegExp(regexp_str, '');
            $currentNode = $this.$_tree;
            $currentNode = new TextRandomizator_Node($currentNode);
            $currentNode.set_type('series');
            $currentNode = $currentNode.concat('');
    		//while(($match = /\\\\|\\[|\\]|\\\{|\\\}|\\\+|\\\||[\+|\+|\{|\}|[|]|\||[^\\\+\{\}[]\|]+/.exec($text)) != null) {
    		while(($match =  $regexp.exec($text)) != null) {
    			switch ($match[0]) {
    				case '\\\\':
    				case '\\':
    					$currentNode = $currentNode.concat('\\');
    					break;
    				case '\\+':
    					$currentNode = $currentNode.concat('+');
    					break;
    				case '\\{':
    					$currentNode = $currentNode.concat('{');
    					break;
    				case '\\}':
    					$currentNode = $currentNode.concat('}');
    					break;
    				case '\[':
    					$currentNode = $currentNode.concat('[');
    					break;
    				case '\]':
    					$currentNode = $currentNode.concat(']');
    					break;
    				case '\\|':
    					$currentNode = $currentNode.concat('|');
    					break;
    				case '[+':
    					if('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set('isSeparator', true);
    					break;
    				case '+':
    					if ($currentNode.get('isSeparator') == true) {
    						$currentNode.set('isSeparator', false);
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('+');
    					}
    					break;
    				case '{':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set_type('synonyms');
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case '}':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'synonyms' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('}');
    					}
    					break;
    				case '[':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case ']':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'mixing' == $is.get('type') && $is.get('parent')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat(']');
    					}
    					break;
    				case '|':
    					var $is = $currentNode.get('parent');
    					if ($is && 'series' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('|');
    					}
    					break;
    				default:
    					$currentNode = $currentNode.concat($match[0]);
    			}
    			$text = $text.substr($match[0].length);
    		}
    		
    	$this.get_text = function($rand) {
    		return $this.$_tree.get_text($rand);
    	}
    
    	$this.num_variant = function() {
    		return $this.$_tree.num_variant();
    	}
    }
    
    var rm_text = new TextRandomizator([[TEXT]])
    var rm_text_random = true
    [[SPINTAX_TEXT]] = rm_text.get_text(rm_text_random)
    

    Вот тестовый скрипт для наглядности.


  • administrators

    Давненько сюда ни кто ни чего новевнького не скидывал. Не помню, кто на форуме спрашивал, можно ли видоизменить лог, чтобы убрать вывод id действия например:
    0_1547309292653_6b06f535-97ea-4463-80d6-9e0244581ec7-изображение.png
    Для этого нужно переопределить функцию log, к сожалению сама функция лога находится в C++ коде и немного изменить её не получится, но можно воспользоваться функцией log_html()


    Вдруг кто не в курсе, переопределять функцию нужно в действии "выполнить код". Отображение действия изменится только после переопределения, то есть если нужно изменить вывод всех действий "лог", значит выполнять код нужно в самом начале скрипта.


    Лог без id действия 0_1547310031022_50372e75-1923-450a-a269-227f6d8cabd7-изображение.png

    //здесь могла быть ваша реклама :D
    function log(text) {
        var tm = new Date();
        var h = tm.getHours();
        var m = tm.getMinutes();
        var s = tm.getSeconds();
        if (h < 10) h = "0" + h;
        if (m < 10) m = "0" + m;
        if (s < 10) s = "0" + s;
        var time_ = "[" + h + ":" + m + ":" + s + "]"
        Logger.WriteHtml("<span style='color:#FFFFFF'>" + time_ + " Поток№ " + thread_number() + ": " + text + "</span>", time_ + " Поток№ " + thread_number() + ": " + text);
    }
    

    Лог без времени 0_1547310211630_d5a16a74-acee-4cf4-8f11-3d52707d4832-изображение.png

    //здесь могла быть ваша реклама :)
    function log(text) {
        Logger.WriteHtml("<span style='color:#FFFFFF'>Поток №" + thread_number() + " : " + text + "</span>", "Поток №" + thread_number() + " : " + text);
    }
    

    Лог без номера потока 0_1547310328436_1ab2e055-5aae-44e7-9911-757bac1ea752-изображение.png

    //здесь могла быть ваша реклама :)
    function log(text) {
        Logger.WriteHtml("<span style='color:#FFFFFF'>" + text + "</span>", text);
    }
    

    Лог без текста 0_1547310407603_3f7fe19a-d487-4297-b2ad-02a34d7f3733-изображение.png
    На случай если нужно программно отключить вывод сообщений в лог.

    //здесь могла быть ваша реклама :)
    function log(text) {}
    

    Вот тестовый скрипт для примера.



  • Для читабельности созданной в BAS конструкции разработчик рекомендует использовать функции. И отделять таким образом логические разделы скрипта.
    Однако у этого метода есть свои недостатки (пусть кому-то они и покажутся мелочными):

    1. Если следовать рекомендациям разраба, многие функции будут использованы лишь один раз, что противоречит общей идеологии функций в программировании. Они просто будут захламлять список функций и усложнят поиск тех, которые используются в скрипте по нескольку раз.
    2. При копировании функций из одного скрипта в другой, необходимо предварительно объявить функцию. А лучше - объявить, вызвать и скопировать все действия. Встречал ошибки при несоблюдении подобной последовательности (возможно из-за кривизны рук).

    Для решения задачи из п.2 применил простой и доступный всем метод:
    Разделение логических разделов скрипта через условный оператор IF и единичку в условиии с описанием раздела. Увидев скриншот сразу станет понятнее:
    0_1547448550531_d7eefa61-6657-4f0f-a244-3005b4cbdac4-image.png
    После добавления функционала сворачивания вложенных конструкций стало совсем удобно. При необходимости каждый раздел разворачивается и нужные данные редактируются. Для пущей красоты можно раскрасить "разделы".
    С таким разделением можно не боясь проблем копировать готовые конструкции из одного скрипта в другой. В приведенном скриншоте каждый из разделов создавался отдельно, каждый в автономном скрипте.

    Конечно же у этого метода есть недостатки связанные исключительно с отсутствием у них возможностей функций, а именно:

    1. Удалив конструкцию, она пропадет из скрипта навсегда, тогда как при использовании функций вложенные действия остаются объявленными и их можно снова вызвать.
    2. Не получится использовать рекурсию. Частично заменил метками. Использовать их рекомендую только в самых простых конструкциях.
    3. Если очень хочется запустить часть скрипта в несколько потоков, всё-таки придется использовать функции =)

    Можно использовать такой метод для многократного повторения однотипных действий в скрипте. Аргументов у функций в BAS по прежнему нет. Так что можно как при использовании функций, объявить или присвоить значение какой-либо переменной, которая будет использоваться уже внутри конструкции. Однако следует помнить, что вновь добавленные в конструкцию экшны не будут добавлены в скопированные. Так что тут удобство сомнительно. Тут уж на вкус, цвет и внимательность.

    Оперировать кубиками в таком скрипте намного удобнее, чем в функциональном. Не нужно искать нужную функцию в списке. К тому же всегда видно, что и где будет использоваться.

    Может уже было. Может кому-то бесполезно. Жду факелы =)


  • administrators

    Есть ещё одна вещь, ради которой я не хочу создавать отдельную тему. Но вряд ли её кто-нибудь заметил.

    Это появление плагина Spoiler на форуме. Для создания спойлера можно воспользоваться кнопочкой на панели:
    0_1547467062558_fb8ed0dd-f7ab-47f4-8cb3-2ca7567e1b56-изображение.png

    После нажатия появится код

    
    
    
    

    Который на форуме будет выглядить вот так:
    0_1547467243595_06a63b02-49f5-49fb-bc22-7247bafd11e7-изображение.png
    0_1547467275803_2828136c-fcc5-4391-801a-4d85131e3a8b-изображение.png



    Важные момент в переопределении функций BAS, выполнять код нужно для каждого потока.

    0_1547467511179_4fff101c-69dc-483a-9eec-9a158b35ff9a-изображение.png

    Вот тестовый скрипт