Forum in READ ONLY mode! All questions and discussions on Discord official server, invite link: https://discord.gg/VxsGzJ7

OpenBox - Гарантированное открытие бокса (для RunUO)

Only working scripts
Alexej
Novice
Novice
Posts: 79
Joined: 06.06.2008 11:55
Contact:

OpenBox - Гарантированное открытие бокса (для RunUO)

Post by Alexej »

OpenBox.inc

Code: Select all

Procedure OpenBox(Box: Cardinal); 
var opboxi: Integer;
    
begin
  opboxi:=0;
  If FindTypeEx($FFFF,$FFFF,Box,True) = 0 Then
  begin
  repeat
    UseObject(Box);
    Wait(500);
    CheckSave;
    AddToSystemJournal('open $'+IntToHex(Box,8));
    FindTypeEx($FFFF,$FFFF,Box,True);
    opboxi:=opboxi+1;
  until (FindCount > 0) or (opboxi > 50); 
  wait(100);
  end;
end; 
Подключается:
{$Include 'OpenBox.inc'}

Используется:
OpenBox(Sunduk);
или
OpenBox(BackPack);

Sunduk и BackPack - Cardinal
и могут задаваться как $XXXXXXXX;
Last edited by Alexej on 14.01.2010 18:18, edited 1 time in total.
WladL
Apprentice
Apprentice
Posts: 240
Joined: 27.07.2009 17:21
Location: DRW
Contact:

Post by WladL »

помоему лишнее использовать FindType внутри цикла, ибо стелс начнет перебирать итемы, заполнять поля FindCount,FindQuantity,...
и все это для того чтоб узнать открылся ли контейнер?
Есть же переменная которую стелс заполнит при открытии сам(LastContainer) нужно просто ее проверить.

Code: Select all

while (LastContainer<>Box) do
	begin 
		UseObject(Box);
		CheckSave;
		wait(1000);
	end;
Last edited by WladL on 13.10.2009 21:20, edited 1 time in total.
grundick
Developer
Developer
Posts: 272
Joined: 31.01.2008 21:16

Post by grundick »

Всё гениальное - просто :roll:
Mirage
Novice
Novice
Posts: 90
Joined: 18.07.2009 19:41

Post by Mirage »

чисто рази любопытства - может быть лучше вот так?

Code: Select all

UseObject(Box);
wait(100);
CheckSave;
while (LastContainer<>Box) do
	begin 
		UseObject(Box);
		wait(300);
		CheckSave;
	end;
вроде выигрываются несколько миллисекунд
:roll:
Vano
Neophyte
Neophyte
Posts: 24
Joined: 31.01.2008 23:26

Post by Vano »

Mirage wrote:чисто рази любопытства - может быть лучше вот так?
Есть такая фича, что сначала изменяется LastContainer, а потом уже приходит содержимое контейнера. Т.е. после изменения LastContainer ящик может быть пустым для стелса.
Хоть мне и не нравится оригинальная реализации "гарантированного открытия", но она лучше, чем предложенный Вами вариант.
WladL
Apprentice
Apprentice
Posts: 240
Joined: 27.07.2009 17:21
Location: DRW
Contact:

Post by WladL »

Нужно просто поставить задержку после выхода из цикла гарантирующюю прибытие данных о содержании ящика.

Code: Select all

while (LastContainer<>Box) do 
   begin 
      UseObject(Box); 
      wait(300); 
      CheckSave; 
   end;
CheckSave;
wait(2000);
Ради интереса проверил....
Условия теста:Коннект чара, запуск скрипта (и так 5 раз )

1)тест кода на основе LastContainer

Code: Select all

tStart:=now;
UseObject(Cont_Res);
while (LastContainer<>Cont_Res) do
		begin 
			wait(100);
			CheckSave;
		end;
//check Data
FindTypeEx($FFFF,$FFFF,LastContainer,false);
while (FindCount=0) do
begin
	FindTypeEx($FFFF,$FFFF,LastContainer,false);
	wait(100);
end;
tEnd:=now;
AddToSystemJournal('tEnd - tStart = '+TimeToStr(tEnd-tStart));
00:26:35.883 [MyLog]: tEnd - tStart = 00:00:00.109
00:44:45.415 [MyLog]: tEnd - tStart = 00:00:00.110
00:45:09.180 [MyLog]: tEnd - tStart = 00:00:00.109
00:46:26.305 [MyLog]: tEnd - tStart = 00:00:00.109
00:46:47.008 [MyLog]: tEnd - tStart = 00:00:00.109

2)Тест кода на основе FindTypeEx (в реализации автора, только убрал вывод сообщения в журнал и изменил внутреннюю задержку на конкурентноспособную)

Code: Select all

tStart:=now;
 opboxi:=0; 
  If FindTypeEx($FFFF,$FFFF,Cont_Res,True) = 0 Then 
  begin 
  repeat 
    UseObject(Cont_Res); 
    Wait(100); 
    CheckSave; 
    //AddToSystemJournal('open $'+IntToHex(Box,8)); 
    FindTypeEx($FFFF,$FFFF,Cont_Res,True); 
    opboxi:=opboxi+1; 
  until (FindCount > 0) or (opboxi > 50); 
  tEnd:=now;
	AddToSystemJournal('tEnd - tStart = '+TimeToStr(tEnd-tStart)); 
  end;
00:30:34.493 [MyLog]: tEnd - tStart = 00:00:00.110
00:42:17.055 [MyLog]: tEnd - tStart = 00:00:00.219
00:42:30.915 [MyLog]: tEnd - tStart = 00:00:00.110
00:43:12.618 [MyLog]: tEnd - tStart = 00:00:00.219
00:43:32.149 [MyLog]: tEnd - tStart = 00:00:00.109

1) Время работы каждого цикла в обоих скриптах (9-10мс+Wait(100))*кол-во циклов.
2) FindTypeEx 2 раза сработал только со 2го прохода цикла.

Выводы:
Циклы проверки вскрытия контейнеров работают практически с одной скоростью.
И никаких "мифических" задержек по поводу опоздания прихода данных у LastContainer я не заметил.
Vano
Neophyte
Neophyte
Posts: 24
Joined: 31.01.2008 23:26

Post by Vano »

WladL wrote:И никаких "мифических" задержек по поводу опоздания прихода данных у LastContainer я не заметил.
Раз тестируете, то надо тестировать правильно...
1. Ваш первый скрипт будет работать явно не быстрей второго, а всё из-за вот этих строк:

Code: Select all

FindTypeEx($FFFF,$FFFF,LastContainer,false);
while (FindCount=0) do
begin
   FindTypeEx($FFFF,$FFFF,LastContainer,false);
   wait(100);
end; 
Т.е. в конечном счете, скрипт ожидает хотя бы одного предмета. Просто в Вашем случае это никак не проявилось.
2. Подход к тестированию явно не верный, раз на раз не приходится и тестирование двумя скриптами ничего кроме статистики Вашего соединения не даст.

Теперь моё тестирование:
1. Чтобы лучше показать все эффекты, интернет соединение было полностью загружено.
2. Скрипт:

Code: Select all

Var
	i: cardinal;
	StartTimer:cardinal;
	Chest: array of cardinal;
	flag : boolean;

begin
	Chest:=[$4019D513,$40330F64,$401831E5,$402B2AA1,$4008AA4B,$403C5562,$403CC8A1,$4011B0C2,$4019CFE8,$4008D769];
	for i:=0 to 9 do
	begin
		flag:=false;
		UseObject(Chest[i]);
		StartTimer:=Timer;
		while (LastContainer<>Chest[i]) do
			wait(10);
		AddToSystemJournal(IntToStr(i)+'-1: '+IntToStr(Timer-StartTimer));
		while (FindType($FFFF,Chest[i])=0) do
		begin
			if not flag then
			begin
				AddToSystemJournal(IntToStr(i)+' waiting...');
				flag:=true;
			end;
			wait(10);
		end;
		AddToSystemJournal(IntToStr(i)+'-2: '+IntToStr(Timer-StartTimer));
	end;
end.
3. Результаты.
№1:

Code: Select all

17:53:31 [Vano]: Character Vano Connected.
17:53:39 [Vano]: Compiling
17:53:39 [Vano]: Compiled succesfully
17:53:40 [Vano]: 0-1: 861
17:53:40 [Vano]: 0-2: 861
[...Здесь всё ok...]
17:53:49 [Vano]: 6-1: 1472
17:53:49 [Vano]: 6 waiting...
17:53:54 [Vano]: 6-2: 5898
17:53:55 [Vano]: 7-1: 952
17:53:55 [Vano]: 7-2: 952
17:53:59 [Vano]: 8-1: 4446
17:53:59 [Vano]: 8 waiting...
17:54:04 [Vano]: 8-2: 9563
17:54:14 [Vano]: 9-1: 9464
17:54:14 [Vano]: 9-2: 9464
17:54:14 [Vano]: Succesfully executed
17:54:14 [Vano]: Script TestOpen.sc stopped successfuly
17:54:55 [Vano]: Character Vano Disconnected.
№2:

Code: Select all

[...ok...]
18:10:07 [Vano]: 7-1: 641
18:10:07 [Vano]: 7 waiting...
18:10:10 [Vano]: 7-2: 3495
18:10:11 [Vano]: 8-1: 821
18:10:11 [Vano]: 8 waiting...
18:10:14 [Vano]: 8-2: 4156
18:10:15 [Vano]: 9-1: 821
18:10:15 [Vano]: 9-2: 821
18:10:15 [Vano]: Succesfully executed
18:10:15 [Vano]: Script TestOpen.sc stopped successfuly
4. Выводы: То что содержимое приходит после обновления LastConteiner'a очевидно.
WladL wrote:Нужно просто поставить задержку после выхода из цикла гарантирующюю прибытие данных о содержании ящика.
По результатам тестов видно, что задержки достаточно большие, и 2000мс приведенные Вами в примере явно недостаточны. Более того, статические задержки должны использоваться только в редких случаях.

P.S. такие эффекты были замечены только на контейнерах содержащих большое число предметов (больше 100). Первые 5 контейнеров содержат меньше 100 предметов, и на них ни разу не было замечено подобной проблемы.
WladL
Apprentice
Apprentice
Posts: 240
Joined: 27.07.2009 17:21
Location: DRW
Contact:

Post by WladL »

С основными выводами вынужден согласиться.
И подозреваю , что задержка будет представлять проблему как при плохом интернет соединении так и при перегрженном сервере. В остальных случаях подобным поведением можно пренебречь, но не желательно (для более уверенной работы скрипта).
Признаю себя не правым... :oops:
Alexej
Novice
Novice
Posts: 79
Joined: 06.06.2008 11:55
Contact:

Post by Alexej »

может оно с ластконетйнером и проще, но негарантировано, т.к. часто надо сундук отуріть раз 20-30 чтобі в нем чегото нашло, вот поєтому и біло такое чудо изобретено
Alexej
Novice
Novice
Posts: 79
Joined: 06.06.2008 11:55
Contact:

Post by Alexej »

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

Code: Select all

Procedure OpenBox(Box: Cardinal); 
var a,opboxi: Integer;
    b: String;

begin
  opboxi:=0;
  If FindTypeEx($FFFF,$FFFF,Box,True) = 0 Then
  begin
  repeat
    UseObject(Box);
    Wait(500);
    CheckSave;
    AddToSystemJournal('open $'+IntToHex(Box,8));
    FindTypeEx($FFFF,$FFFF,Box,True);
    opboxi:=opboxi+1;
    
    If (BMSearch(0, Copy(GetCliloc(Box),0,Length(GetCliloc(Box))), 'Contents: ') > 0) Then 
  begin
    b:=Copy(Copy(GetCliloc(Box),0,Length(GetCliloc(Box))), Pos('/', Copy(GetCliloc(Box),0,Length(GetCliloc(Box))))-3, 255);
    If (BMSearch(0, b, '/') > 0) Then Delete(b, Pos('/', b), 255); 
    If (BMSearch(0, b, ':') > 0) Then Delete(b, Pos(':', b), Pos(':', b));
    If (BMSearch(0, b, ' ') > 0) Then Delete(b, Pos(' ', b), Pos(' ', b));
    a:=StrToInt(b);
//    AddToSystemJournal(IntToStr(a));
  end;
  until (FindCount > 0) or (opboxi > 50) or (a = 0); 
  wait(100);
  end;
end; 
WladL
Apprentice
Apprentice
Posts: 240
Joined: 27.07.2009 17:21
Location: DRW
Contact:

Post by WladL »

может не стоит поиск числа делать?
повесить проверку на первый символ после имени, типа если <>'0' тогда там что-то есть,а больше в принципе и не нужно, главное знать что он не пуст.
"Как хочешь ты трудись;
Но приобресть не льстись
Ни благодарности, ни славы,
Коль нет в твоих трудах ни пользы, ни забавы. (с) С.Крылов."
Alexej
Novice
Novice
Posts: 79
Joined: 06.06.2008 11:55
Contact:

Post by Alexej »

я прицепил с полной читалкой числа кол-ва итемов, может кому пригодится именно готовая читалка числа итемов в паке/сундуке и тд...
это из читалки дюры с итема подогнал... там по веселее все было... долго я ее рисовал.. ну полгодика дык точно :)
редко вдохновение посещало :)
User avatar
Vizit0r
Developer
Developer
Posts: 3958
Joined: 24.03.2005 17:05
Contact:

Post by Vizit0r »

Vano wrote:
Mirage wrote:чисто рази любопытства - может быть лучше вот так?
Есть такая фича, что сначала изменяется LastContainer, а потом уже приходит содержимое контейнера. Т.е. после изменения LastContainer ящик может быть пустым для стелса.
Хоть мне и не нравится оригинальная реализации "гарантированного открытия", но она лучше, чем предложенный Вами вариант.
добрался сегодня до этого дела. итак, небольшая теория процесса:
1) идет даблклик
2) приходит 24 пакет, в котором айди запрашиваемого контейнера и его моделька (для рисования клиентом, но это неважно).
3) пакет 3C, в котором идет кол-во айтемов в контейнера и их перечисление со всеми параметрами (кроме тултипа, но это опять же неважно).
дальше.
переменная LastContainer меняется 24 пакетом. так что да, в теории скрипт может отработать быстрее, чем обработается 3C.

Что мы имеем на практике:
1) Сервер формирует эти два пакета в связке, и в 99% случаев они идут один за другим
2) стелс все же мультипоточный, и пока скрипт обрабатывается - 3C пакет успеет пережеваться.

вывод - описанный баг может произойти ТОЛЬКО в случае больших и очень больших пакетов 3C - когда в контейнере где-то от 20-30 айтемов и больше.

Чтобы такого небыло - прицеплю смену переменной к 3C, хотя там есть свои сложности.
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Vizit0r wrote:когда в контейнере где-то от 20-30 айтемов и больше.
Насколько мне помнится, на скриптах редко когда надо было заглядывать в контейнеры, где айтемов меньше. Обычное явление - число айтемов в контейнере не меньше 100, а чаще всего приближается к 255.
User avatar
Vizit0r
Developer
Developer
Posts: 3958
Joined: 24.03.2005 17:05
Contact:

Post by Vizit0r »

зависит от сервера :)

впрочем, это уже исправлено
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
Post Reply