Изучаем скрипты WP. Часть третья
Вообще-то я планировал написать данную статью через неделю после выхода второй части. Но неделя это
слишком много. Данная растрата времени для нас не позволительна, более того за такой длительный срок
можно забыть содержание первых двух частей. Извиняюсь за изменения в расписании. Итак продолжим
обучение.
Во второй части, если вы ещё помните, вам было дано домашнее задание - получить исходник для файла
wpbox.xml. Подробно объяснять данный исходник я не буду, а лишь остановлюсь на основных моментах.
Как так спросите вы? Хотелось бы подробное описание как во второй части, т.е. каждой строчки кода.
Дело в том, что исходник получился достаточно объёмным и если объяснять каждую строчку, статья
получится слишком большой. А когда объём статьи большой, читатель изучает её беглым взглядом, т.е.
не вчитывается в каждую строчку, некоторые строчки вообще не читает. В итоге обучение получается
не эффективным, что крайне не допустимо.
Более того у скрипта много минусов. Во-первых, он собирает только бонусные коробки (грузовые коробки
он не подбирает). Во-вторых, данный скрипт собирает не все бонусные коробки, а лишь вновь
появившиеся. Т.е. те коробки, которые уже есть в космосе, скрипт не подберёт.
Надеюсь я вас убедил, что данный скрипт не требует детального рассмотрения. Более того, к этому
скрипту мы ещё вернёмся не раз и рано или поздно все непонятные моменты пропадут.
Итак, вот исходник скрипта:
-----------------------------------------------------------------------------
Код:
// Скрипт сбора коробок на движке FS
var slist: TStringList;
var lastPackStartPos,lastPackEndPos,LastTmrCode: Integer;
var BoxCode1,BoxCode2,BoxCode3: string;
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
var
I,X: Integer;
Len, LenSubStr: Integer;
begin
if Offset = 1
then Result := Pos(SubStr, S)
else
begin
I := Offset;
LenSubStr := Length(SubStr);
Len := Length(S) - LenSubStr + 1;
while I <= Len do
begin
if S[I] = SubStr[1]
then
begin
X := 1;
while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
Inc(X);
if (X = LenSubStr)
then
begin
Result := I;
Exit;
end;
end;
Inc(I);
end;
Result := 0;
end;
end;
procedure OnCreate;
begin
try
slist:=TStringList.Create;
slist.add('ozims');
slist.add('1604u');
slist.add('znmjs');
slist.add('bu9m9');
slist.add('zel71');
slist.add('q4knx');
slist.add('ci7m0');
slist.add('1ukl6');
slist.add('1gtlm');
slist.add('180fk');
slist.add('13b44');
slist.add('ntr63');
slist.add('1lmf1');
slist.add('1r78f');
slist.add('1oloo');
slist.add('xixzz');
slist.add('13jaa');
slist.add('6dge9');
slist.add('m79jj');
slist.add('h0rbx');
slist.add('n5cwr');
slist.add('1hviz');
slist.add('1g4pv');
slist.add('1ss4t');
slist.add('1c2tu');
slist.add('100vp');
slist.add('rku9c');
slist.add('1hd2h');
slist.add('416n4');
slist.add('1t5p4');
slist.add('6ovbk');
slist.add('3k2hr');
slist.add('48chq');
slist.add('lnkdf');
slist.add('1usjy');
slist.add('1scn2');
slist.add('usc1j');
slist.add('qj4o9');
slist.add('yyr28');
slist.add('3mtlo');
slist.add('hkw3g');
slist.add('a2abg');
slist.add('1fnxl');
slist.add('1kjds');
slist.add('9icg0');
slist.add('13umf');
slist.add('qtqry');
slist.add('1ucay');
slist.add('puvoe');
slist.add('1c3oi');
slist.add('1nesl');
slist.add('wl0wr');
slist.add('sn8n9');
slist.add('1v20m');
slist.add('1g568');
slist.add('1malf');
slist.add('w27x1');
slist.add('ov57p');
slist.add('1ecek');
slist.add('1my80');
slist.add('1srvg');
slist.add('2u942');
slist.add('103wa');
slist.add('1srrl');
slist.add('109xs');
slist.add('6x1u8');
slist.add('152g8');
slist.add('5naot');
slist.add('oeoud');
slist.add('tbeuu');
slist.add('13p97');
slist.add('rckbt');
slist.add('1trob');
slist.add('1fsi3');
slist.add('v2qxb');
slist.add('1szeq');
slist.add('87k2a');
slist.add('1bfcm');
slist.add('fc9f7');
slist.add('1g7du');
slist.add('lqzp9');
slist.add('wbku5');
slist.add('1ts89');
slist.add('1ag6n');
slist.add('10tv0');
slist.add('49ol8');
slist.add('1isk4');
slist.add('1jyqj');
slist.add('1e5au');
slist.add('8v03f');
slist.add('uy62u');
slist.add('mk797');
slist.add('1g65j');
slist.add('hm27v');
slist.add('hs940');
slist.add('q0e4a');
slist.add('bv8wq');
slist.add('1nad0');
slist.add('1mc48');
slist.add('1801q');
except
slist:=nil;
WriteLogln('Ошибка инициализации объекта TStringList');
end;
LastTmrCode:=3;
end;
procedure OnDestroy;
begin
if slist<>nil then slist.Free;
end;
function OnTimer(var ntimer,count:integer):boolean;
begin
gSys.SetTimer(ntimer,0);
if ntimer = 1 then gSys.SendS(HStr('787C')+ BoxCode1 + HStr('0A00'));
if ntimer = 2 then gSys.SendS(HStr('787C')+ BoxCode2 + HStr('0A00'));
if ntimer = 3 then gSys.SendS(HStr('787C')+ BoxCode3 + HStr('0A00'));
end;
begin
if _gFromServ
then
begin
lastPackStartPos:=1;
lastPackStartPos:=Pos('0|c|',copy(_gBuff,lastPackStartPos,length(_gBuff)-lastPackStartPos+1));
while not (lastPackStartPos<1)do
begin
if StrCmp(copy(_gBuff,lastPackStartPos+9,3),'|2|')
then
begin
if not (slist.IndexOf(copy(_gBuff,lastPackStartPos + 4,5)) > -1)
then
begin
gSys.sleep(75);
if LastTmrCode = 1
then
begin
LastTmrCode := 2 ;
gSys.SetTimer(2,700);
BoxCode2 := copy(_gBuff,lastPackStartPos + 4,5);
end
else
begin
if LastTmrCode = 2
then
begin
LastTmrCode := 3;
gSys.SetTimer(3,700);
BoxCode3 := copy(_gBuff,lastPackStartPos + 4,5);
end
else
begin
if LastTmrCode = 3
then
begin
LastTmrCode := 1;
gSys.SetTimer(1,700);
BoxCode1 := copy(_gBuff,lastPackStartPos + 4,5);
end;
end;
end;
end;
end;
lastPackStartPos := PosEx('0|c|',_gBuff,lastPackStartPos + 1);
end;
end;
end.
--------------------------------------------------------------------------------
Некоторые строчки исходника могут немного отличаться от исходника-оригинала, это связано с
особенностями перевода. Тем не менее это никак не отражается на работе скрипта.
Теперь небольшой комментарий к исходнику.
Мы уже с вами знакомы с переменными. Здесь лишь отмечу, что переменные бывают двух типов:
глобальные и локальные. Глобальные переменные отличаются от локальныех лишь расположением в
коде. Глобальные переменные располагаются в начале кода и доступны всей программе. Локальные
переменные располагаются внутри процедуры или функции и доступны соответственно только той
процедуре или функции, внутри которой они находятся. Запомните, что локальные переменные
не доступны для основного кода, поэтому если вы всё же хотите их использовать, вам потребуется
их повторно объявить.
Кстати небольшой совет по переменным. Создавайте переменные несущие смысловую нагрузку, как это
сделано например в данном исходнике.
Например вы хотите создать переменную, обозначающую сторону квадрата. Естественно вы можете
обозвать эту переменную как угодно, но лучше для этого использовать общепринятые сокращения или
же использовать транслит:
var iuiuifdf:integer; // так содавать переменные не следует
var a: integer // нужно делать так, здесь используется общепринятое сокращение для обозначения
//стороны квадрата
var StoronaKvadrata: integer; // так тоже можно, здесь используется транслит
Используя транслит, обратите внимание, что самостоятельные слова начинаются с большой буквы.
Итак, вернёмся к нашему исходнику.
Тип string нам уже знаком - это строка.
integer также как и string это стандартный тип. Означает integer - целое число.
TStringList - это стандартный класс. Означает TStingList - список строк.
Чтобы больше не возвращатся к этому вопросу приведу здесь все возможные стандартные типы:
Boolean = boolean (fvtBool);
Char : char (fvtChar = fvtString);
String : string (fvtString);
Variant : variant (fvtVariant);
Pointer : variant (fvtVariant);
Array : array (variant fvtArray)
Integer , Byte, Word, Longint, Cardinal, Tcolor : integer (fvtInt);
Real, Single, Double, Extended, Currency, TDate, TTime, TDateTime, : Real (fvtFloat);
Константы:
'True' : boolean = true;
'False' : boolean = false;
'nil' : variant = 0;
'Null' : variant = null;
Вернёмся к нашему коду.
После переменных идёт функция PosEx. Это стандартная функция Delphi, поэтому объяснять её здесь
не буду. Отмечу лишь различие между функцией и процедурой. Единственное отличие процедуры от
функции заключается в том, что функция возвращает рузультат, а процедура нет. Вот и всё отличие.
Далее по коду у нас идёт процедура OnCreate. Это стандартная процедура, которая вызывается
каждый раз при компиляции.
Далее идёт связка try...expect. Данная конструкция нужна для отлова запрещённых событий.
Т.е. если при работе скрипта встретится исключение, которое указано в блоке try, то управление
скриптом передастся блоку expect.
Как вы уже могли догадаться именно в эту конструкцию и помещаются коды коробок-ловушек. Всего этих
ловушек 100, если не верите можете сами посчитать.
Где и как посмотреть список актуальных на данный момент коробок-ловушек, читайте здесь:
http://zhyk.ru/forum/showpost.php?p=533485&postcount=1
Дальнейший код объяснять не буду, статья итак получилась большой. Тем более кроме обновления
кода коробок-ловушек, больше в коде вам ничего не потребуется.
Многое пока остаётся не понятным, но не пугайтесь. С каждой последующей главой вы будете узнавать
всё больше и больше. Ну а пока изучайте, экспериментируйте и ждите следующих глав.