SRL Archive - Help and Support

Blacklisting Items.


kingarabian

2012-02-15 17:56:53

I just saw Coh3ns thread on blacklisting items e.g using an items pixel count and color to differentiate between items.

I was wondering if someone can write a tutorial on this? Or show me how… Because I HATE DTM's, always had bad luck with them and Bitmaps use up extra valuable memory IMO so I don't think they are efficient.

PatDuffy

2012-02-15 17:59:01

I have been interested in this also, but would it even be effective now with the frequent graphical glitches in the inventory?

kingarabian

2012-02-15 18:00:39

From: PatDuffy
I have been interested in this also, but would it even be effective now with the frequent graphical glitches in the inventory?


It may, but I still want to learn.

Kyle Undefined

2012-02-15 18:12:31

Basically you just do
CountColor(131072, Box.X1, Box.Y1, Box.X2, Box.Y2);

That counts the outline on the item in the Box you pass in. You would use it like this:
BL := CountColor(131072, Box.X1, Box.Y1, Box.X2, Box.Y2);
if(BL = 20)then
WriteLn('Found item.');

Bonfield

2012-02-15 18:14:02

I like them but inventory items keep changing so it thiws it out making it useless, the way I have done it was to check the blackcount of the item, the length of the TPA and the width then check for a unique colour, the easiest way to keep it organized is to create a record for your objects when I get home I will see what code I still have on my computer it might be easier to understand


Sorry for the wall of text, massive pain to post off an iphone


From: Kyle Undefined
Basically you just do
CountColor(131072, Box.X1, Box.Y1, Box.X2, Box.Y2);

That counts the outline on the item in the Box you pass in. You would use it like this:
BL := CountColor(131072, Box.X1, Box.Y1, Box.X2, Box.Y2);
if(BL = 20)then
WriteLn('Found item.');

That's how I first started using them, but alot if items have the same blackcount eg fire staff and air staff and after speaking to narcle implementing width, height and colour checks you use blacklists more to their full potential

kingarabian

2012-02-15 18:15:01

From: Kyle Undefined
Basically you just do
CountColor(131072, Box.X1, Box.Y1, Box.X2, Box.Y2);

That counts the outline on the item in the Box you pass in. You would use it like this:
BL := CountColor(131072, Box.X1, Box.Y1, Box.X2, Box.Y2);
if(BL = 20)then
WriteLn('Found item.');

Thanks Kyle!
Alright say we want to find Pickaxe's, logs, items that are different but have the same shape. Would this still work?

Edit:
From: Bonfield
I like them but inventory items keep changing so it thiws it out making it useless, the way I have done it was to check the blackcount of the item, the length of the TPA and the width then check for a unique colour, the easiest way to keep it organized is to create a record for your objects when I get home I will see what code I still have on my computer it might be easier to understand


Sorry for the wall of text, massive pain to post off an iphone

THANKS! Appreciate it :).

@Kyle I sure well.

Kyle Undefined

2012-02-15 18:15:01

Narcle uses this idea in his Smelter script, take a look :)

Bonfield

2012-02-15 18:18:52

I was going to say have a look at narcles scripts

I editEd my first post

Kyle Undefined

2012-02-15 18:20:23

From: kingarabian
Thanks Kyle!
Alright say we want to find Pickaxe's, logs, items that are different but have the same shape. Would this still work?

Edit:

THANKS! Appreciate it :).

@Kyle I sure well.


Yeah, it will find all the items that match that black list count, but you can narrow it down by checking if the Rune/Willow/etc color exists in that box.

Bonfield

2012-02-15 18:28:59

Yes you can, I think blacklist are the fastest most effective way to find inventory objects I actually did start writing a tool to create them, I was going to have the script create them during runtime so it would be as easy to have the items in the inventory run the script and it creates everything it needs to run, sort of the system wt uses in his hlr script, I will try to digg it up

kingarabian

2012-02-15 21:27:55

From: Bonfield
Yes you can, I think blacklist are the fastest most effective way to find inventory objects I actually did start writing a tool to create them, I was going to have the script create them during runtime so it would be as easy to have the items in the inventory run the script and it creates everything it needs to run, sort of the system wt uses in his hlr script, I will try to digg it up


Please do. I want to as much reference as I can get. As for the items changing/glitching shape, I think you could make the script log you out if it can't detect the items, and then log you back in? Because if you log out and log back in the items go back to normal.

Bonfield

2012-02-15 23:16:00

I will look for it, but the logging in out makes sense. I have the inventory objects change randomly when banking

Kyle Undefined

2012-02-16 02:24:19

Just have the script auto update if the items glitch, shouldn't be that hard :)

kingarabian

2012-02-16 03:16:50

From: Kyle Undefined
Just have the script auto update if the items glitch, shouldn't be that hard :)


Yeah I'm not too worried about it. Hows it going Bon :D?

Bonfield

2012-02-16 03:55:53

i couldnt find it sorry, i wrote this just then though
program new;
{$i SRL/srl.simba}

type
Blacklist = record
Name: string;
UpTextArr: string;
OutlineCount: Integer;
Width: Integer;
Height: Integer;
Colour: Integer;
OutlineTPA: TPointArray;
end;

var
StaffOfAir, RandomItem: Blacklist;

function LoadBlacklist: Blacklist;
begin
with StaffOfAir do
begin
Name := 'Staff of air';
UpTextArr := 'of air';
OutlineCount := 70;
Width := 25;
Height := 29;
Colour := 13090494;
end;
end;

function CreateItem(BlackCount, ItemWidth, ItemHeight, UniqueColour: Integer; BlackTPA: TPointArray): Blacklist;
begin
with Result do
begin
OutlineCount := BlackCount;
Width := ItemWidth;
Height := ItemHeight;
Colour := UniqueColour;
OutlineTPA := BlackTPA;
end;
end;


function GetInvItem(Slot: Integer): Blacklist;
var
t: Integer;
ItemTPA: TPointArray;
ItemBox: TBox;
Unique: TPoint;
Item: Blacklist;
begin
t := GetSystemTime;
ItemBox := InvBox(Slot);
FindColorsTolerance(ItemTPA, srl_outline_black, ItemBox.x1, ItemBox.y1, ItemBox.x2, ItemBox.y2, 0);
ItemBox := GetTPABounds(ItemTPA);

Unique := MiddleTPA(ItemTPA);
Item := CreateItem(Length(ItemTPA), iAbs(ItemBox.x2-ItemBox.x1), iAbs(ItemBox.y2-ItemBox.y1), GetColor(Unique.x, Unique.y),
ItemTPA);
Result := Item;
writeln('GetInvItem = ' + ToStr(Result)+ ' '+IntToStr(GetSystemTime-t)+'ms');
Exit;
end;

function CompareBlacklist(var Item1, Item2: Blacklist; UpText: String): Boolean;
var
t: Integer;
RandomPoint :TPoint;
ItemText : String;
begin
if (not LoggedIn) then Exit;
if (GameTab(tab_Inv)) then
begin
t := GetSystemTime;
if (Item1.OutlineCount = Item2.OutlineCount) and (Item1.Width = Item2.Width) and (Item1.Height = Item2.Height)
and (Item1.Colour = Item2.Colour) then
begin
RandomPoint := MiddleTPA(Item1.OutlineTPA);
MMouse(RandomPoint.x, RandomPoint.y, 5, 5);
Wait(150+random(35));
ItemText:=GetUpText;
writeln('Item text is : '+ItemText);
if (Pos(UpText,ItemText) > 0) then
begin
writeln('Found '+UpText+' in uptext');
writeln('CompareBlacklist = ' + ToStr(Result)+ ' '+IntToStr(GetSystemTime-t)+'ms');
Result:=True;
Exit;
end else
writeln('Cannot find uptext');
Result:=False;
Exit;
end else
writeln('False, Blacklists different');
end else
writeln('CompareBlacklist not in gametab');
end;

begin
setupSRL();
LoadBlacklist;
ActivateClient;
wait(1000);
GameTab(tab_Inv);
RandomItem := GetInvItem(1);
CompareBlacklist(RandomItem, StaffOfAir, 'air');
end.

havent tested it it should work may not =]

what are you planning on making?

kingarabian

2012-02-16 04:12:27

From: Bonfield
i couldnt find it sorry, i wrote this just then though
what are you planning on making?

Geez thanks mate!!! Nothing specific right now… I plan to script again it's been a while. I just wanted a template so I could use for all my scripts. A specific way in finding items, a specific way in walking, and a specific way in interacting with NPC's/Object's.

WT-Fakawi

2012-02-16 04:20:42

From: kingarabian
Geez thanks mate!!! Nothing specific right now… I plan to script again it's been a while. I just wanted a template so I could use for all my scripts. A specific way in finding items, a specific way in walking, and a specific way in interacting with NPC's/Object's.


I have been bragging for this for ages. I have made my own feeble attempt at blacklist with HLR.

Copied from SSRL:

Because I wanted it soo badly, I wrote it myself. (Because I am to nooberish to comprehend any other code but my own). Just look five seconds at my HLR video and you will instantly understand why this is what we have needed for years. And what was written already by Niels, and to a certain agree before him by masquerader (amount still works?) and probably by many others before them.

The general paradigm is simple:

being able to runtime refer to objects with their 'name'!


Advantage: i.e. straight from HLR: Cook('Raw'). Cooks any kind of food it grabs. Because all food is 'Raw'. Still impressed it works with any kind of food.
Also from HLR: burn('log'). Mind you: I do not know what a 'log' is until I analyse it (and add it to the database) runtime it in my inventory!

Never, ever having to make a dtm, or a bitmap for any object anymore. Just a name, thats all. What a relief that would be!


Philosophy.

  1. The Item Database is kept locally, on every users's computer. (Can be skipped, but you loose the database when script stops.)
  2. The Item Database is updated (or when skipped 1. created) runtime.
  3. Inventory/Bank/Equip is constantly monitored, scanned and database is accordingly updated as part of FindNormalRandoms!

This would be my preferred approach. You choose if you store the database locally on your computer or in memory (or both). I would really avoid "Central Servers" with a "Dynamically Regenerated ItemBase" etc for legal purposes. Nice for internettraffic, but no thank you. Just a plain text file with a string, and a couple of numbers, thats all we need really. Nothing copyrighted.


Implementation.

I am sorry, I am not an expert in that area. I have not been able to grasp Nielsie's code. I have asked for a solution in this thread. Ray solved it in the last post. But alas, I was unable to comprehend this, so I partly reinvented the wheel myself.
I used:
  1. Object width and height. (Filters 80%)
  2. Number of outlined pixels, better known as or blacklist. (Filters 95%)
  3. For the remaining 5% I use one stupid pixel-color-integer no other object shared in my DB. (More precise: the sum of 25 pixels filtered in a strict grid from the background noise ) Super stupid, but superfast. One integer, ghehe, works 100%. Should of course be replaced by a sophisicated sum of blah, or w/e you prefer. Also Bank and Equip can be scanned if preferred (with or without mouse scanning (depending on the "needs" of the database engine: is the outline familiair? is the checksum ok?)

loo tong;ridn't deed: Make it so!


Functionality.

This is what I have come up with in HLR:

-finding-

Function CountInvObj(name:String): Integer; // Returns sum of name.
Function CountAnyNamedInvObj(name:String): Integer; // Returns sum of any instance of name.
Function FindInvObj(var slot: Integer; name: String): Boolean; // Finds name and returns slotnumber and boolean.
Function FindAnyNamedInvObj(var Slot: Integer; name:String): Boolean;// Finds any instance of name and returns slotnumber and boolean.

-clicking-

Function ClickInvObj(name: String; Left:Boolean): Boolean; // clicks name, Left or Right.
Function ClickAnyNamedInvObj(name: String; Left:Boolean): Boolean; // clicks any instance of name, Left or Right.

-misc-

Function Name2DBase(Name: String):InvItem; // returns Type InvItem from name.
Function RepairInv:Boolean; // compares and fixes the current inventory to the existing database: Error check (bones and white areas distorting UpText analysis)

You will probably come up with or already have come up with more FindInvObjEx-functions.

Can you all agree on this being a nice starting point? I would definately go for the "simple" approach, nothing too fancy maybe. All code has been written more then once before here. Argh… Just make it work!

DataBase.

The Db should be as simple as:

  • Object name
  • Object Height, Object Width
  • Object outline count
  • Object colors

In a textfile like this:

'Rune Hatchet', 28, 32, 108, {2345066,24355056, 80594903, 7060493}
'Willow log', 26, 26, 78, {26584,59349329, 90923439, 37231279}

So for every object you have once investigated, you will have one line in your textfile. The format of the textfile corresponds to the itemdatabase, so we can search through the file and read it into our script at runtime. New objects found at runtime will be added to the textfile. We add the toplevel function UpdateItemDatabase to FindRandoms.

Thats all there is to it really.

Also in many cases, the object width and height alone are enough to distinguish your objects…. so you dont need to re-scan them.



That is how far I have come.

kingarabian

2012-02-16 04:46:47

Very nice Fawk, I wish you luck!

@Bonfield thanks a bunch this is awesome lol.

Bonfield

2012-02-16 04:48:14

Wow I had the same idea, although the cook('raw') is amazing, I went about it the wrong way in how I tried to compare everything and ended up with massive procs and couldn't get my head around how to do it as every way I thought of doing or kept getting more and more complex, when I saw you post hlr it got me wanting to finish my long abandoned project and I got to something like what I posted earlier. Storing everything locally is a great idea

I wonder how many times the same concept has been tried? You have clearly succeeded, the first I saw was yohojo then Neils


Great job seeing this through, out of curiosity Often is your system used in ssrl?


I have always been curious as to speed comparisons between blacklists dtms bitmaps etc, can you shed any light here wt?

So what I posted works king?

kingarabian

2012-02-16 05:07:03

From: Bonfield
Wow I had the same idea, although the cook('raw') is amazing, I went about it the wrong way in how I tried to compare everything and ended up with massive procs and couldn't get my head around how to do it as every way I thought of doing or kept getting more and more complex, when I saw you post hlr it got me wanting to finish my long abandoned project and I got to something like what I posted earlier. Storing everything locally is a great idea

I wonder how many times the same concept has been tried? You have clearly succeeded, the first I saw was yohojo then Neils


Great job seeing this through, out of curiosity Often is your system used in ssrl?


I have always been curious as to speed comparisons between blacklists dtms bitmaps etc, can you shed any light here wt?

So what I posted works king?


Yes sir! It works perfectly.

Come to think of it, if Fawki can expand his project, we could solve dungeoneering at ease. Create run time objects and solve those puzzles.

Bonfield you should most definitely work on this and try to get objects/Npc's. That would be nuts!

Bonfield

2012-02-16 05:19:27

i will start working on it, mind if i annoy you with a few pms along the way?

did you have to edit what i posted much? did i post a func to print the height, width, length, blackcount etc?

WT-Fakawi

2012-02-16 05:39:57

From: Bonfield
Wow I had the same idea, although the cook('raw') is amazing, I went about it the wrong way in how I tried to compare everything and ended up with massive procs and couldn't get my head around how to do it as every way I thought of doing or kept getting more and more complex, when I saw you post hlr it got me wanting to finish my long abandoned project and I got to something like what I posted earlier. Storing everything locally is a great idea

I wonder how many times the same concept has been tried? You have clearly succeeded, the first I saw was yohojo then Neils


Great job seeing this through, out of curiosity Often is your system used in ssrl?


I have always been curious as to speed comparisons between blacklists dtms bitmaps etc, can you shed any light here wt?

So what I posted works king?


I think the main problem with this is: how evolved do we want this to be? I have made it childishly simple, but it works for me ( check out also my Moss G. Scruipt in beta now…same principles apply)

This concept is as-far-as-i-can-see only been implemented in my scripts. The theory has been invented a couple of times now, but afaik never been actually implemented inside a working SRL-script.

Speed is of no importance to me. I need it to work. RS is a very sloooow game, so we have all the time in the world.

Bonfield

2012-02-16 05:53:51

Yeah saw you post your moss g script, definitely going to pick through that

I congratulate you on making this work so well, who cares if it's 'childishly simple' it works and works well

My original concept was item recognition without up text but I might see how far I can take this

WT-Fakawi

2012-02-16 06:05:07

there are a couple of problems with my system…and I know the answers too :smile:
  • Inventory object should be outline scanned and the unique colors within the boundaries should be stored. The background noise and the yellow amount noise needs to be filtered out. (This is difficult, since a change in amount yields a change in the object. In my crude system, I just rescan them again, pf)
  • In the database there should also be a stack/amount flag, indicating the amount of objects on that spot.
  • Obviously this wont work for objects that have the same shape and color, like seeds….but we still have the name. So a flag should be made for those rare cases where the object are identical.


  • Once again, the endless advantages are limitless. If we get this to work, then we'll never have to make another DTM/bitmap again.
  • Aaaand, if Jagex decides to change all the objects (like they recently did with armour) we are still 100% fine!
  • Aaand, we can script for things we don't even know about. Click('Lamp') for instance.