1. Пишем свой первый скрипт. Начало.

spec аватар

 С чего нужно начинать написание скрипта? На мой взгляд, любой кто решил написать скрипт должен четко понимать следующее:

  • Что он делает. Каков будет конечный результат.
  • Ясно понимать что делает каждая строчка написанного им скрипта.
  • Поискать решение аналогичных задач в исходниках или других проектах.
  • Возможно, переписать все по-своему :)

Давайте для начала создадим простенький скрипт. Который по команде будет выводить содержимое некого текстового файла. Но прежде чем что-то создавать подробно разберем шаги, которые обычно предпринимаются при написании нового скрипта: анализ существующих примеров и разбор реализации похожих вещей в исходных текстах.

Начнем разбор с тестового скрипта change_nick.bsh, идущего в комплекте с дистрибутивом JimBot.

import ru.jimbot.modules.AbstractServer;
import ru.jimbot.util.*;
import ru.jimbot.modules.chat.*;
import ru.jimbot.modules.*;
Данный фрагмент дополняет область видимости программы скрипта. В данном случае добавляются класс AbstractServer, который является интерфейсом к любому сервису бота (и чату, и анекботу). Далее импортируются все классы из util, chat и modules. Подробнее их можно посмотреть в исходниках.
При запуске скрипта в него передаются ссылки на следующие переменные:
  • cmd - переменная возвращает экземпляр класса ChatCommandProc, в котором обрабатываются все команды бота. Прошу обратить внимание при копировании его исходников, при обращении к методам этого класса не забывайте добавлять переменную cmd.
  • proc - возвращает экземпляр класса IcqProtocol. Это активный процесс приема-передачи сообщений, через который пришла данная команда. Для ответа юзеру напрямую нужно поместить ответ в очередь исходящих этого процесса. Иначе - в общую очередь чата для рассылки всем присутствующим.
  • msg - текст сообщения, содержащий нашу команду. Его можно проанализировать на предмет передачи дополнительных параметров.
  • uin - УИН того кто отправил эту команду.

Двинемся дальше.В следующем блоке кода происходит установка скрипта как обработчика команды. Выполняется при запуске бота. При выполнении самой команды - игнорируется.

//Установка скрипта как обработчика команды
if(in.equals("install")){
	cmd.addCommand("!chnick", new Cmd("!chnick","$n $c",39,name));
	cmd.addAuth("chnick","команда изменения ника другого пользователя");
	out="Ok";
	return;
}
Далее мы видим проверку полномочий. Происходит вызов методов класса ChatCommandProc через переменную cmd. В первой строке происходит проверка на то в чате ли пользователь, и не админ ли он. Админам позволительно запускать команду находясь вне чата. Во второй строке происходит проверка на заданный объект полномочий. Его мы заменим на свой для своей команды.
// Проверим полномочия
if(!cmd.isChat(proc,uin) && !cmd.psp.testAdmin(uin)) return;
if(!cmd.auth(proc,uin, "chnick")) return;

Оторвемся немного от анализа скрипта и вспомним зачем мы вообще все это затеяли. Нам нужно написать скрипт для вывода содержимого текстового файла. Вспомним, где мы такое уже видели? В команде !help и !rules. Полезли в исходный текст класса ChatCommandProc в поисках реализации этих команд.

    	commands.put("!help", new Cmd("!help","",2));
    	commands.put("!chat", new Cmd("!chat","",3));
    	commands.put("!exit", new Cmd("!exit","",4));
    	commands.put("!rules", new Cmd("!rules","",5));
    	commands.put("!stat", new Cmd("!stat","",6));
    	commands.put("!gofree", new Cmd("!gofree","",7));
    	commands.put("!go", new Cmd("!go","$n",8));
    	commands.put("!invite", new Cmd("!invite","",9));

Мы видим, что код функции !help - 2, найдем где происходит ее вызов.

            switch (tst){
            case 1:
                proc.mq.add(uin,MainProps.getAbout());
                break;
            case 2:
                commandHelp(proc, uin);
                break;
            case 3:
                goChat(proc, uin);
                if(psp.getBooleanProperty("chat.getUserInfoOnChat"))
                    proc.mq.add(uin, "", 1); //proc.recUserInfo(uin,"0");
                break;
            case 4:
                exitChat(proc, uin);
                break;

Видим, что для кода 2 происходит вызов метода commandHelp нашего класса. Найдем его реализацию ниже.

    /**
     * !help
     */
    private void commandHelp(IcqProtocol proc, String uin){
        String[] s = psp.getHelp1().split("<br>");
        for(int i=0;i<s.length;i++){
            proc.mq.add(uin,s[i]);
        }        
        if(srv.us.authorityCheck(uin, "exthelp")){
            s = psp.getHelp2().split("<br>");
            for(int i=0;i<s.length;i++){
                proc.mq.add(uin,s[i]);
            }
        }        
    }

 Все оказалось не так просто как мы думали :) В данном месте вы получаем готовое значение текстовой переменной, уже прочитанное из файла, разбиваем его на куски и выводим пользователю. Будем копать дальше. Найдем определение переменной psp.

    private long new_ver_test_time = 0;
    public ChatProps psp;
    private boolean firstStartMsg = false;

Это оказался объект класса ChatProps. Теперь нужно найти этот класс и реализацию в нем метода getHelp1().

    public String getHelp1(){
        return loadText("./text/help1.txt");
    }
    
    public String getHelp2(){
        return loadText("./text/help2.txt");
    }

    public String loadText(String fname){
        String s = "";
        try {
            BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(fname),"windows-1251"));
            while (r.ready()) {
                s += r.readLine() + "\n";
            }
            r.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return s;
    }

Вот в общем то и все. Мы видим, что метод loadText полностью нам подходит - читает заданный текcтовый файл и возвращает его содержимое в виде строковой переменной. Более того, этот метод объявлен как public, значит мы можем использовать уже созданный экземпляр класса ChatProps для вызова этого метода. Чем и займемся в следующей серии :)

Продолжение следует...

3.666665
Your rating: Нет Average: 3.7 (3 votes)