PDA

Просмотр полной версии : ShortCutInit\Управление вторым окном


Breadfan
22.07.2010, 01:39
Где-то встречал идею о переносе панелей скилов из пакета ShortCutInit - у когонть наработки имеются?

J-Fobos
22.07.2010, 20:30
О переносе куда?

Breadfan
22.07.2010, 20:47
Грубо говоря мысль такова:
1. есть 2 окна (1 - главное, 2 - саппорт\ассистент)
2. набор скилов с одной из панелей 2го окна - передаются в 1ое (например одна полоска с рутом\слипом и т.д.) - это приведет к отображению в 1ом клиенте панели 2го
3. вызов скилов с этой панели перехватывается и отправляется на сервер от имени 2го

Не перенос скилов между окнами) Просто вариант управления 2ым окном. Он будет более менее-универсален для разных проф, просто потребуется выставить нужные скилы (которые будут задействованы, к примеру рут\блок вв и прочее, что иногда хочется использовать) на одну из панелей, к примеру на 10ю, откуда ярлыки будут считаны и переданы в клиент 1, причем в самом скрипте править ничего не придется, все будет делаться в клиенте 2

Придется писать отдельную процедуру для распознавания пакета ShortCutInit, т.к. его структура записей в нем различна, в зависимости от ярлыков панели (ярлыки скила\макроса\банки - записываются по разному. Вот из исходников кусочек кода:{
private static final String _S__57_SHORTCUTINIT = "[S] 45 ShortCutInit";

private L2ShortCut[] _shortCuts;
private L2PcInstance _activeChar;

public ShortCutInit(L2PcInstance activeChar)
{
_activeChar = activeChar;

if (_activeChar == null)
return;

_shortCuts = _activeChar.getAllShortCuts();
}

@Override
protected final void writeImpl()
{
writeC(0x45);
writeD(_shortCuts.length);

for (L2ShortCut sc: _shortCuts)
{
writeD(sc.getType());
writeD(sc.getSlot() + sc.getPage() * 12);

switch(sc.getType())
{
case L2ShortCut.TYPE_ITEM: //1
writeD(sc.getId());
writeD(0x01);
writeD(-1);
writeD(0x00);
writeD(0x00);
writeH(0x00);
writeH(0x00);
break;
case L2ShortCut.TYPE_SKILL: //2
writeD(sc.getId());
writeD(sc.getLevel());
writeC(0x00); // C5
writeD(0x01); // C6
break;
case L2ShortCut.TYPE_ACTION: //3
writeD(sc.getId());
writeD(0x01); // C6
break;
case L2ShortCut.TYPE_MACRO: //4
writeD(sc.getId());
writeD(0x01); // C6
break;
case L2ShortCut.TYPE_RECIPE: //5
writeD(sc.getId());
writeD(0x01); // C6
break;
default:
writeD(sc.getId());
writeD(0x01); // C6
). Хотя если передавать панель с однотипными ярлыками - то все будет нормально.

Можно, конечно, все это сделать в виде массива, и вызывать по команде в чат, но в принципе большая часть скрипта будет одинаковой, а в случае с таким переносом - намного нагляднее
--------------------------------------------------------

Обновлено: не, настолько внаглую не получится, надо как-то подругому пробовать.................

J-Fobos
22.07.2010, 23:01
Отличная идея, да и на первый взгляд не сложная в реализации.

В грации эпилог пакет с клавишами выглядит следующим образом:
45 = id
05 00 00 00 = количество используемых клавиш
................
01 00 00 00 =тип клавиши (итем)
00 00 00 00 =позиция (в данном случаи F1)
BC AF 41 10 =ObjectId итема
01 00 00 00 = хз
FF FF FF FF = хз (вроде как количество, но не уверен)
00 00 00 00 = хз
00 00 00 00 = хз
00 00 00 00 = хз
..................
02 00 00 00 =тип клавиши (скил)
01 00 00 00 =позиция (в данном случаи F2)
64 00 00 00 =id скила
0F 00 00 00 =лвл скила
00 = хз
01 00 00 00 = хз
.....................
03 00 00 00 =тип клавиши (действие)
02 00 00 00 =позиция (в данном случаи F3)
00 00 00 00 =id действия (в данном случаи сесть)
01 00 00 00 =хз что, но для всех действий всегда такой
.......................
04 00 00 00 =тип клавиши (макрос)
03 00 00 00 =позиция (в данном случаи F4)
E8 03 00 00 =id макроса
01 00 00 00 = хз что, но для всех макросов всегда такой

Рецептов у меня в сумке не было, так что их я не смотрел. Собственно исходя из выше написанной информации можно написать следующую обработку пакета (в виде массива считаю хорошим решением).

var
type1,slot,id,lvl,a1,a2,a3,a4,a5,a6,a7,a8,a9:array [0..99] of integer;
//массивы клавиш, 100 значений потому что максимум 100 клавиш.
//массивы а будут использоваться для хранения неизвестных параметров пакета.
//согласен что не оптимально объявлять 9 массивов неизвестных значений:)

procedure ShortCutInit;

var
count,i,number:integer;

begin

number:=2;//позиция "курсора" в пакете

count:=ReadD(2); //количество используемых клавиш

for i:=0 to count do
begin

type1[i]:=ReadD(number); //смотрим тип клавиши

case type1[i] of

1:begin //обрабатываем клавишу с итемом
slot[i]:=ReadD(number+4);
id[i]:=ReadD(number+8);
lvl[i]:=ReadD(number+12);
a1[i]:=ReadD(number+16);
a2[i]:=ReadD(number+20);
a3[i]:=ReadD(number+24);
a4[i]:=ReadD(number+28);
a5[i]:=ReadD(number+32);
number:=number+36; //перемещаем курсор на следующую клавишу
end;

2:begin //обрабатываем клавишу со скилом
slot[i]:=ReadD(number+4);
id[i]:=ReadD(number+8);
lvl[i]:=ReadD(number+12);
a6[i]:=ReadC(number+16);
a7[i]:=ReadD(Number+17);
number:=number+21; //перемещаем курсор на следующую клавишу
end;

3:begin //обрабатываем клавишу с действием
slot[i]:=ReadD(number+4);
id[i]:=ReadD(number+8);
lv[i]l:=ReadD(number+12)
a8[i]:=ReadD(number+16);
number:=number+20;
end;

4:begin // обрабатываем клавишу с макросом
slot[i]:=ReadD(number+4);
id[i]:=ReadD(number+8);
lvl[i]:=ReadD(number+12)
a9[i]:=ReadD(number+16);
number:=number+20;
end;

5:begin
//а тут надо рецепт дописать, но времени нету :)
number:=number+0;
end;
end;
end;
end;

Дальше надо будет изменить пакет что пойдет в главное окно (в принципе получается что вторичное окно надо будет грузить до того как загружено главное). Код примерно такой:
for i:=1 to count do
case slot[i] of
12:begin {тут изменим клавишу что предлагает сервер, значения возьмем с ранее полученных массивов}end;//если клавиша для F1 второй панельки
13:begin{тут изменим клавишу что предлагает сервер} end;//если клавиша для F2 второй панельки
14:begin{тут изменим клавишу что предлагает сервер} end;//если клавиша для F3 второй панельки
end;
Это уже будем править под себя пакет пакет с главного окна.


PS: не уверен в правильности кода, писал в блокноте :)

Breadfan
23.07.2010, 03:45
Ну (как я думаю), в данном варианте рецепты и рассмотривать не стоит, т.к. расчитывается скрипт на использование в замесах\фарме, где лучше не переключаться меж окон, либо на использование вместе с отключенным клиентом (NoCloseServerAfterClientDisconnect; )
Поправлю: максимум - 120 клавиш (10 панелек по 12). Так же можно в любой момент вызвать пакет ShortCutInit - добавив и тут же убрав любой скил\банку\макрос на панель.

В данный момент считывает 10ю панельку у 'donor' (кнопки отвечающие условию slot>107) и в виде набора макросов передает в главное окошко. Макрос в названии и акроним имеют ИД скила (впоследствии надо изменить акронимы), внутри он же - т.е. при его нажатии перс в общий чат пишет этот ИД. Запись названия скила убрал из-за кривости руссификации серверной части - после релога русские символы в макросе превращаются в наборы вопросительных знаков, так что куски использующие работу с SkillsID.INI - можно будет смело выкинуть, или заменить файл его английский версией ...
При этом передаются лишь скилы - остальное пока не стал создавать. Напрямую передать - попытка провалилась) Ярлык скила появляется - но серый, при его нажатии пакетов годных для обработки клиент не отправляет к сожалению, так что немного изменил принцип.

Теперь необходимо добавить части обрабатывающие пакеты от 'rec' - своевременно убивать их, не давая попасть на сервер, и включать скил\прочее в клиенте 'donor', соответственно запроса, ну и часть следящую за таргетом...На пару минут копаний ;)

Добавлено через 1 час 34 минуты
Кстати, надо будет оценить, насколько жестко он будет относиться к уже имеющимся макросам :)

Breadfan
23.07.2010, 03:59
Может сразу сделать работу только с макросами имеющими определенное имя (напр. cut1, cut2...cut12), и проверять наличие свободных ячеек под вновь создаваемые - что бы не переживать за сохранность ранее созданных

Пока вылилось в "это":

const
rec='Lapeno';
donor='Freya';
var
SkillsNameEng,ItemsNameEng,StringList:TStringList;
i,ii,iii,SKID,Slot:integer;
SkillID:integer;
Pskill:array[1..12] of string; //массив с именами скилов панельки
PskillID:array[1..12] of integer;//массив с ИД --//--
values:array[0..100] of variant;
procedure Init; //Вызывается при включении скрипта
begin
StringList:=TStringList.Create;
SkillsNameEng:=TStringList.Create;
ItemsNameEng:=TStringList.Create;
try
SkillsNameEng.LoadFromFile('skillseng.ini');
except
Sendmsg('SkillsidEng.ini не найден!');
exit;
end;
try
ItemsNameEng.LoadFromFile('itemseng.ini');
except
Sendmsg('ItemsIDEng.ini не найден!');
exit;
end;
end;
procedure Free; //Вызывается при выключении скрипта
begin
end;
//основная часть скрипта
//вызывается при приходе каждого пакета если скрипт включен
begin
if fromserver and (connectname=donor) and (pck[1]=#$45) then begin //InitCut
i:=(ReadD(2)); //kol-vo Cuts
Sendmsg('Kol-vo Cuts: '+Inttostr(i));
ii:=6;
for iii:=1 to i do begin

case (ReadD(ii)) of
1:begin //item
ReadMask('ddddddhh',2,values);
ii:=ii+28;
end;

2:begin
//skill
Slot:=ReadD(ii);
SKID:=ReadD(ii);
ReadD(ii);
ReadC(ii);
ReadD(ii);
if (slot>107) then begin //Запись только с 10ой панельки
Pskill[(slot-107)]:=(SkillsNameEng.Values[InttoStr(SKID)]);
if (Pskill[(slot-107)]='') then Pskill[(slot-107)]:=('Unkn: '+Inttostr(skid));
PskillID[(slot-107)]:=skid;
Sendmsg(Pskill[(Slot-107)]+' ID skill: '+inttostr(PskillID[(slot-107)]));
Sendmsg('Slot '+Inttostr(slot));
Sendmsg('SKID '+Inttostr(SKID));
buf:=#$CD;
WriteMask('DSSSCCCCDCS',[(15+(slot-107)),((Pskill[(Slot-107)])),'',(Inttostr(SKID)),0,1,1,3,0,0,('Use Skill: '+inttostr(PskillID[(Slot-107)]))]);
Sendmsg(Strtohex(buf));
Sendtoserverex(rec);
end;
end;

3:begin //social action
ReadMask('ddd',2,values);
ii:=ii+12;
end;

4:begin //macro
ReadMask('ddd',2,values);
ii:=ii+12;
end;

5:begin //recipe
ReadMask('ddd',2,values);
ii:=ii+12;
end;

end;
end;
end;

if fromclient and (connectname=rec) and (pck[1]=#$49) and (Copy(ReadS(2),1,10)='Use Skill:') then begin
SkillID:= StrtoInt(Copy(ReadS(4),11,4)); //из команды в чат считываем ИД скила
pck:=''; //
buf:=#$39; // формируем пакет MagicSkillUse
WriteMask('ddc',[SkillID,0,0]); // и отправляем его
Sendtoserverex(donor); // в клиент 'donor'
end;
end. - Пока что оно "переносит" только скилы, не бегает за 'rec', не меняет таргет, не делает прочего, чего бы туда ни хотелось засунуть :) Только включает скилы со своей 10ой панели (предварительно таргет надо взять)
И все бы ничего, но только зарраза чат блокирует периодически, при спаме макроса :D

PS: файлы skillseng.ini и itemseng.ini - взяты от более старой версии - L2phx 3.2.1, изза этого будут недочеты...

supernewbie
24.07.2010, 23:29
Я делал такое :)

Помоему не проще ли

begin
if FromServer and (ConnectName=Name1) and (pck[1]=#$45) then
begin
buf:=pck;
SendToClientEx(Name);
end;
end;

PS это если надо перенести панель с одного перса на другого. Перед этим еще придется переносить СкиллЛист и ИтемЛист, это давольно удобно при написании скрипта "Вселение", который вселяет в перса от которого есть только соединение)

Breadfan
25.07.2010, 00:01
Это вообще явно не такое. К чему мне полностью замененная панель? в моем варианте - добавляются макросы на панель Главного, в твоем же - произойдет полная замена. Я смысла от такого "вселения" не вижу - ты заменишь скиллист, итемлист - а к чему это все? проще без извращений сразу в окне с бафером быть
У меня так: в главном окне формируется набор макросов, повторяющих скилы выставленные на 10ую панель ведомого окна. При нажатии макрос в чат выдает текстовую команду use skill xxxx (ид скила) - команда перехватывается и отправляется на ведомый клиент. Ведомый, получив такую команду и юзает соответствующий скил на цель находящуюся в таргете у Главного. Простейший пример применения: лук в связке с пп - берет в таргет цель, жмет макрос на своей панели (пп берет в таргет ту же цель и кидает ей рут) и спокойно расстреливает...Выделяет себя - бафает ченть или может хильнутся - как угодно....
Можно то же самое сделать написав обработчик наподобие "если от клиента А в чат "используй 1" то --> в клиенте Б включить скил 1" НО: для каждого отдельного перса придется создавать свой обработчик команд, в зависимости от набора имеющихся скилов, моя же цель - создание унифицированного скрипта, минимизирующего правку и подгонку под разные профы\случаи: сегодня бегаю луком и пп, а завтра - спойлером + овер

Breadfan
25.07.2010, 19:49
В итоге вышло: бегает за ведущим не тыкая по нему (соответственно удерживая нужную цель в таргете), а используя координаты перемещения, юзает свитки ТП, стараясь использовать то же что и ведущий, держит в таргете ту же цель что и ведущий. Диапазон разницы координат при перемещении при старте равен 99, в процессе может меняться командой в чат "mult XX", где х - 0..99, либо нажатием Соц.Действий "Да"\"Нет" - с шагом 10. Порядок запуска - запустить скрипт, открыть сумку бота (в лог L2PHX выведет инфу о наличии сое: тип 1 - сое, 2 - соеКХ, 3 - соеЗамок), принять его в пати (будут считаны необходимые ИД персов). Макросы в главном окне - имеют имя - ИД скила, акроним - его название (необходима англ. версия файла SkillsID.ini под именем skillseng.ini !!! - от одной из старых версий подойдет переименованный) - сформировать набор скилов на 10ой панели( если это необходимо) и на какой либо другой (1-9) переместить туда-сюда любой ярлык (перемещать надо для формирования пакета ярлыков).
Если бегаете с mult не сильно маленьким - то лучше маленькими перебежками не передвигаться, иначе саппорта болтать начинает, как г... в проруби :) НЕ бьет с Ctrl (хотя это можно подправить при желании в блоке формирования пакета скила), не тепешится от гк одновременно с ведущим, НЕ тестировалась работа при отключенном клиенте (да и нет там пары кусков для такого).
Гонял в основном связку тх+пп, и под конец написания тх+спойл, так что замечания - только приветствуются :D
Файлы из архива files.rar кинуть в корень папки L2phx
Хроники: Грация Финал (ну судя по тому что на моем сервере написано :))
Обновлено:
mod_2: добавлена возможность управления сумонами - тестировалось на ПП(ведущий)+гном с чайником
изменение дистанции разбега - соц.действием Да\Нет
включить\выключить зажатый контрол - соц.действие Bow - действует на перса и на его сумона (при наличии) Названия макросов управления сумоном - пока обезличены, имеют в названии лишь ИД скилов

Kilatif
25.07.2010, 21:40
Вообще интересная идея.. Сам бы занялся, имея бы достаточные знания вообще о пакетах, о написании скриптов... Спасибо)

Breadfan
25.07.2010, 21:53
Рано) Оно еще не обкатано толком :)

supernewbie
25.07.2010, 22:05
Это вообще явно не такое. К чему мне полностью замененная панель?
у меня было так, нажимаешь на булку, пишешь "в него" и у тебя инвентарь булки, скилы булки, панелька булки, и ты юзаешь скиллы\вещи у себя в окне а юзает булка :)

Breadfan
25.07.2010, 22:06
Покажи

supernewbie
25.07.2010, 22:25
потом я еще делал юз скила на булке при слове в чат за главного, скрипт скину позже

PS сразу предупреждаю: он написан в страшно нубском стиле, там нету отступов, пометок, дохрена лшиних бегинов и эндов и работает он в 90% случаев :lol:

Breadfan
25.07.2010, 22:51
не, мне был необходим вариант именно одновременной согласованной работы в бою, а не переключение по очереди. В моем я могу прицепить сразу трех и управлять ими безо всяких лишних переключений

supernewbie
25.07.2010, 22:59
ну эт не интересно) тем более полностью управлять ты ими не сможешь

Breadfan
25.07.2010, 23:02
ну, например, от спойлера - сколько надо? 3 скила - спойл\фестиваль\свип...в связке с пп - мне надо рутить им да и все собсно...и так далее....

supernewbie
25.07.2010, 23:04
ясно, в любом случае, зачем тебе панели тогда там какие-то? приписывай действия булок по словам или соц.действиям от главного

Breadfan
25.07.2010, 23:09
:D Вообщето, там и так сделана передача команд через чат, просто чтобы вручную не делать в скрипте черт знает какой список команд на разные профы, и не запоминать их - сделано по другому :D Скрипт сам считывает скилы выставленные на 10ю панельку и по ним формирует набор команд. Получается готовый макрос с командой, с названием вызываемого скила - а сам пользователь не заморачивается чего там в чате вводить требуется. Просто жмет и все) Вот как-то так:

supernewbie
25.07.2010, 23:41
Оо, клева) не додумался так сделать) так можно сделать 10 панель - свм, 9 - сд, 8 - дк)

dyh9l
26.07.2010, 05:07
Очень хорошая задумка, я верю в тебя у тебя все получится!!! :)

Breadfan
26.07.2010, 09:01
у кого-нибуть есть табличка скилов для сумонеров? я о скилах управления сумонами - они ж управляются через...RequestActionUse: (например) 56 16 00 00 00 01 00 00 00 00 - атака....А вручную ее рисовать - да я столько сумонов не переберу, чтоб составить ее вручную :scratch_one-s_head:

Kilatif
26.07.2010, 12:42
Кстати на счет того что через макросы бан чата идет... Я сделал так что бы в макрос писало не просто текст, а команду /dismiss после которой через пробел пишется id скила и поставил вместо обработки пакета 45, 49 пакет (RequestOustPartyMember). В итоге получается что за большое количество запросов команды бан за флуд не дается и все юзается

Breadfan
26.07.2010, 18:48
Ок, спасибо) Чето я о таком и не додумался вовсе) переделаю под такой вариант использования. Чуть позже правленый вариант выложу, с возможностью подключения сумонера с сумоном

Kilatif
26.07.2010, 19:05
Еще есть 1 вариант... Немного сложноват в реализации, но зато намного привычнее и удобнее. Пока нет времени, что бы попробовать сделать, потом может займусь. В общем.. Вот как говорил supernewbie, можно перетащить скилы с одной панели на другую. Т.е. что бы были видны именно иконки и названия скилов одного чара в окне другого. Ну все это можно делать лишь для того что бы пользователю было легче.. но все же) Так вот... Можно сделать так, что бы перетаскивались не все скилы, а только те, которые нам нужны. Например из панели 10 одного перса на панель 10 другого перса. Но неудобство тут в том, что во-первых, нужно перетаскивать эти скилы еще и из скила листов от одного другому (для того что бы при нажатии от клиента отправлялся пакет использования скила), во-вторых, если с такой панели скил удалять (именно удалять, при перемещении между панелями все нормально), то опять же присылается ShortCutInit, который удаляет "чужие" скилы. Это же происходит если открывать панель скилов и инвентарь (если используешь еще и итемы), но если немного повозиться, то можно придумать обход всему этому

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

Breadfan
26.07.2010, 21:20
Ну все это вполне возможно миновать - сохранив нужные наборы в нескольких массивах, и, при приходе пакета инит - подменять его на требуемое. Дело будет в возне с объединением скилллистов

А у меня в данный момент возня со скилами сумонов :(

Kilatif
26.07.2010, 23:35
Ну я тогда пока помучаюсь со своей идеей, потом выложу сюда скрипт полностью. Скрипт буду писать свой, но некоторые куски буду брать твои, мне так легче. Надеюсь ты не против?)

Breadfan
27.07.2010, 08:16
Да об чем речь - бери конечно :)

Добавлено через 7 часов 34 минуты
Ну начерно каркас набросал примерно вот такой:
//запустить скрипт,в окне donor-переместить ярлык
соц.действ:Greeting-временно вернуть первоначальный вид листа (повторный вызов - выведет опять модифицированный)
//Victory - сбросить все к первоначальному виду

Const
rec='';
donor='';
var
SKkolvo,j,i,ii,iii,isPas,lvl,sID,n:integer;
Slot,SKID:Integer;
Pskill:array[1..12] of string;
proba:array [1..30000,1..2] of string; //небольшой массив для индикации свой\чужой
NewPS:Boolean;
values:array[0..100] of variant;
pckSL:string; //пакет с итемлист
pckSLm,Temp:string; //его моды
procedure Init;
begin
pckSL:='';
Temp:='';
for i:=1 to 30000 do begin
proba[i,1]:='';
proba[i,2]:='';
end;
buf:=#$50;
Sendtoserverex(rec);
end;
procedure Free;
begin
end;
begin
//формируем первоначальный массив со скилами
if fromserver and (pck[1]=#$5F) and (connectname=rec) and (Temp='') then begin
pckSL:=pck; //исходный вид для возможной последующей отмены
pckSLm:=Strtohex(pckSL);
SKkolvo:=ReadD(2);
j:=6;
for i:= 1 to Skkolvo do begin
isPas:=ReadD(j);
lvl:=ReadD(j);
sID:=ReadD(j);
n:=ReadC(j);
if (proba[sID,1]='') then begin
proba[sID,1]:=rec;
proba[sID,2]:=inttostr(lvl);
SendMSG(inttostr(sID)+' '+proba[sID,1]+' '+proba[sID,2]);
NewPS:=False;
end;
end;
end else begin
if fromserver and (pck[1]=#$5F) and (connectname=rec) and (Temp<>'') then begin //избегаем случайного отката
pck:=Temp; // скилл листа
end;
end;
//добавляем в массив скилы, пришедшие с пакетом SkillList
if fromserver and (pck[1]=#$45) and (connectname=donor) then begin
i:=(ReadD(2)); //kol-vo Skills
Sendmsg('Kol-vo Skills: '+Inttostr(i));
ii:=6;
for iii:=1 to i do begin
case (ReadD(ii)) of
1:begin //item
ReadMask('ddddddhh',2,values);
ii:=ii+28;
end;
2:begin //skill
Slot:=ReadD(ii);
SKID:=ReadD(ii);
lvl:=ReadD(ii);
ReadC(ii);
ReadD(ii);
if (slot>107) then begin //Запись только с 10ой панельки
if (proba[skID,1]='') then begin //d - пассивен\нет, d - лвл, d - ид, c - 0
proba[skID,1]:=donor;
proba[skID,2]:=inttostr(lvl);
SendMSG(inttostr(skID)+' '+proba[skID,1]+' '+proba[skID,2]);
NewPS:=False;
buf:=Hstr(pckSLm);
WriteD(0);
WriteD(lvl);
WriteD(skID);
WriteC(0);
pckSLm:=StrtoHex(buf);
//SendMsg(StrtoHex(buf));
skKolvo:=skKolvo+1;
end;
end;
end;
3:begin //social action
ReadMask('ddd',2,values);
ii:=ii+12;
end;
4:begin //macro
ReadMask('ddd',2,values);
ii:=ii+12;
end;
5:begin //recipe
ReadMask('ddd',2,values);
ii:=ii+12;
end;
end;
end;
if (temp='') then begin
Temp:=Copy(buf,6,(Length(buf)-5));
buf:=#$5F;
WriteD(skKolvo); //создание пакета SkillList
buf:=buf+Temp;
SendMsg('105: '+StrtoHex(buf));
Temp:=buf;
Sendtoclientex(rec);
end;
end;
if fromclient and (pck[1]+pck[2]=#$56#$0c) and (connectname=rec) then begin
SendMsg('------Clear Skills--------'); //Greeting - временная очистка скилл-листа
buf:=pckSL;// ну глянуть может там скилы свои, чтоб не путаться...
Sendtoclientex(rec);
end;
if fromclient and (pck[1]+pck[2]=#$56#$0D) and (connectname=rec) then begin
SendMsg('--Rebuild Skills--');//Victory - очистка существующего массива
Temp:='';//для требуемой переделки набора скилов
buf:=pckSL;
pckSL:='';
for i:=1 to 30000 do begin //очистка
proba[i,1]:='';
proba[i,2]:='';
skKolvo:=0;
end;
Sendtoclientex(rec);
buf:=#$50;
Sendtoserverex(rec);
end;
end.

Breadfan
27.07.2010, 08:29
Массив там вставил на 30000 (с запасом :D) - для хранения ID скила и ника персонажа, с которого был считан, чтоб не перебирать его проверками при решении от кого именно слать активацию скила....

Вот наспех бег подключил и ассист.
Управление скилами - не через чат и не через макросы - все свободным остается.
Реагирует на нажатие Ctrl
Пока обкатывается лишь с одним прицепом, да и сам листинг не особо читаем (как же нехватает еще одного монитора НАД основным...или двух...), но дело - движется ;)
Обновлено: добавлена опция управления чужим сумоном.
//каркас, у донора на панельках - только скилы и ничего кроме них!!!
//у donora на 9ую панель поместить ярлыки управления сумоном (если есть)
//на 10ую скилы которые переносить...
//порядок: запустить скрипт, в окне Rec - переместить ярлык на панельке - с одной
//ячейки в другую,
//в окне donor - переместить ярлык 2 раза (считывается за 2 прохода - 1)обычные
//скилы с панели, 2) Ярлыки управления сумоном\ярлыки соц.действий
//принять donor в пати.

//соц.действия: Greeting - временно вернуть первоначальный вид листа (повторный
//вызов - выведет опять модифицированный)
//Victory - сбросить все к первоначальному виду.
//Yes\NO +- разбега при движении
//Bow - вкл\выкл "у donor Ctrl всегда вкл.". (не распространяется на сумона)
//
//Advance - включить\выключить управление чужим сумоном - только при его включении
// будут работать перенесенные ярлыки управления - так же все неиспользуемые скриптом соц.действия будут передаваться от имени donor
-------------------------------
Обновлено: NewGrab4IL - избавился от большого массива, немного поправлены алгоритмы поиска скилов, блок управления сумоном - "состояние неизвестно..." ;) Правда есть нюанс - при лагах и включенном battle-режиме - запекашить самого себя - секундное дело :D
Добавил проверку состояния "в касте" - по идее спамить пакетом MagicSkillUse должен прекратить

Breadfan
28.07.2010, 12:29
Складывается ощущение, что память выделяемая на массив - после выключения скрипта - не освобождается (после нескольких циклов включить-выключить скрипт, время старта скрипта значительно увеличивается, но запоминание пакетов отключено) - я прав? если да - лечится ли это?

QaK
28.07.2010, 21:10
Breadfan, по-идее - должно освобождаться, как-то писал скрипт на мониторинг чаров, тоже делал массив из 3к элементов - тормозов не наблюдалось, при неоднократном перезапуске. Попробуй *.83 версию пакетхака, на ней потестируй, если то же самое - значит амба, фаст скрипт, скорее всего, если нет - значит что-то полоамли.

Breadfan
28.07.2010, 21:21
Ну у меня задействован из 30к элементов - с потолка цифру просто брал, фактически то задействованы будут десяток-другой элементов :D Жутко необоснованое и не рациональное использование памяти) Просто хотелось избежать перебора при поиске ИД скила, но, похоже, лучше вернуться именно к перебору во избежание таких вещей. Первый, второй, третий прогоны - тормозов не наблюдается, но чуть позже - принимает вид жуткой катастрофы....

PS: моя версия - 3.5.33.164, *.83 версия - это 3.4.1.83 ?
//QaK:да

J-Fobos
28.07.2010, 22:22
Если я не ошибаюсь пустая переменная string занимает минимум 256 байт(если в ASCII). А в скрипте мы имеем 2-х мерный массив из этих сток, получается что у нас таблица из строк 30к на 2, итого 60к строк. Каждая по 256 байт. Простая математика: 60000*256 = 15 360 000 байт = 15 Мб.

Освобождается ли память? Включаем/выключаем скрипт 10 раз и смотрим увеличилось ли использование памяти на 150 Мб, это буде заметно.

Говорить об оптимальности использования ресурсов системы не стоит, здесь и так понятно :D

alexteam
28.07.2010, 22:26
string занимает минимум 256 байт
ниправда.
у строки в делфи нет избыточности.
а в фастскрипте там вообще variant

J-Fobos
28.07.2010, 22:55
ниправда.
у строки в делфи нет избыточности.
а в фастскрипте там вообще variant

Извиняюсь, значит плохую книгу читал :unknw:

Занимаемая память линейно зависит от числа символов в строке и начинается с 256 байт. При записи различных значений в эту строку, память занимаемая строкой может только увеличиваться, но не уменьшаться.

Это с книги, а вот с сайта _http://articles.org.ru/cn/showdetail.php?cid=6600

Значение в байте длины может быть меньше, чем размер строковой переменной : Byte(sstr[0]) ‹= SizeOf(sstr). То есть, хотя длина строки может и меняться, память, занимаемая ShortString, всегда равна 256 байтам.

Не знаю насколько правдива эта информация, как приду домой проверю, ради интереса :) Ну а насчет фастскрипта и variant я спорить не могу, здесь я нуб :)


alexteam, так память масива все таки освобождается при выключении скрипта или нет?

Если все же не освобождается, то можно вместо массива использовать List1:TStringList, а потом List1.Free;

Breadfan
28.07.2010, 23:28
да там вместо того жуткого массива на черт-те сколько - вполне возможно впихнуть малый, строк на 50 максимум и все. Необходимо будет немного изменить метод поиска строки и все.

Kilatif
29.07.2010, 00:11
А еще лучше пишите динамику вместо статики и будет вам счастье! =) Правда вот не знаю поддерживает ли фастскрипт динамику... *SCRATCH*

Breadfan
29.07.2010, 12:17
Да не требуются там заморочки с динамичными (кстати - да, вроде как поддерживает), там два массива по 12 строк всего основных - а их перебирать можно по 5 раз за проход, без особых подтормаживаний....
Доделайте, кто-нибуть ;)

mira
11.08.2010, 08:18
для управления окном сделал такую реализацию:
грузиш булок выбираеш соответствующие конфиги
и юзаеш их скилы или тактики заданные иконками как свои

зы не пакетхак но суть примерно таже. теже пакеты тотже фастскрипт

J-Fobos
11.08.2010, 11:36
mira, "не пакетхак но суть примерно таже" ваша разработка? Как называется? :)
Видел похожую прогу л2 ремоут контрол, но там эмульгатор клавиш.

mira
11.08.2010, 12:41
да. Назвал прогу aika
в начальной версии l2inproc
тоже эмулировала клавиши. Щас для ярлыков пишетса скриптовый обработчик. Работает через пакеты.
Кстате матчасть этом форуме помогла респект и идея юзать фс. Исходники пх кстате так и не смарел ;)
в скрипте мейн функция реализует бота а обработчики для ярлыков. некоторые действия в нужное время не выполнит не 1 бот

Kilatif
15.08.2010, 20:25
Ниже мой вариант интерпретации сего... (все равно дома делать нечего)))Сделал все по простому, и лично для меня, более удобно. Тупо добавляет все скилы бота к скилам юзера. А дальше дело простое, выставляете их себе на панельки и юзайте) Таргет бота такой же как и ваш, на ctrl реагирует. На панели можете тягать скилы как хотите: переставлять местами, удалять. Все нормально, ничего вроде бы не сбивается. Позже, если не будет лень, сделаю все поудобнее, уберу всякие грубости в скрипте и прочее (Например что бы не все скилы добавлялись а нужные).

Breadfan
15.08.2010, 20:34
Вот изза этого #$39 : begin
buf := pck;
SendToServerEx(bot);
end; - будет палицца ппц, отправляя то от имени бота запрос на использование несуществующего скила (это когда юзером родной скил юзнешь), то от имени юзера (т.к. ты запрос юзера на сервер не убиваешь)

Kilatif
15.08.2010, 20:39
будет палицца ппц, отправляя то от имени бота запрос на использование несуществующего скила, то от имени юзера (т.к. ты запрос юзера на сервер не убиваешь)

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

Breadfan
15.08.2010, 21:03
Да мне тут J-Fobos гениальнейшее решение проблеммы с массивом подкинул, а продолжать правку скрипта - негде пока :( Сижу в ожидании открытия сервера

Kilatif
15.08.2010, 21:07
нуу.. я буду делать по-своему и выкладывать сюда, а ты чуть что советом помогай) Или оптимизацией какой)

Breadfan
17.08.2010, 19:54
да сам вешаюсь :( Что-то надо менять, осталось выяснить "что" и "где"....

NLObP
18.08.2010, 13:48
Breadfan, ты для какого сервера делаешь? лог пакетов кинь, я посомтрю в пакетхаке. По поводу оптимизации: ифы в кейсы надо переписать.

PS: Packets*.ini дай еще до кучи, плиз.

Breadfan
18.08.2010, 14:05
Последняя версия - под интерлюд сделана, сервер на котором пробую -->> http://lin2fans.net/ (сервер в стадии ОБТ похоже - онлайн 5-6 человек, да и сам сервер не ахти, даже без Phx в 2 окна довольно-таки ощутимы лаги сети)
Лог с танка (реципиент) и мага (донор) - старт в Годдарде, небольшая пробежка к мобам, убийство 2-3 штук. packets.ini - внутри архива
Есть предположение, что желательно ввести проверку "нахожусь ли в состоянии каста", дабы вхолостую не спамить на сервер и не гонять лишние проверки в скрипте.
Обновил скрипт на 3ей странице - добавил проверку состояния "Кастую" донору