Advertisement
WarPie90

ItemFinder

Jan 14th, 2018
463
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 9.79 KB | None | 0 0
  1. var
  2.   ITEM_FINDER_SIMILARITY = 0.92;
  3.   IGNORE_COLORS_L = [0, $FFFFFF, $00FFFF, $80FF00];
  4.   IGNORE_COLORS_R = [0, $FFFFFF, $00FFFF, $80FF00];
  5.  
  6. type
  7.   TRSItemImage = type TMufasaBitmap;
  8.   TRSItemFinder = array of TRSItemImage;
  9.  
  10.   TRSItemMatch = record
  11.     Item, Edge: Double;
  12.   end;
  13.  
  14. var
  15.   ItemFinder: TRSItemFinder;
  16.  
  17. operator >= (Left: TRSItemMatch; Right: Double): Boolean;
  18. begin
  19.   Result := (Left.Item >= Right) and (Left.Edge >= Right);
  20. end;
  21.  
  22. procedure TRSItemImage.FromData(Data: String);
  23. var
  24.   Stream: TStringStream;
  25.   Picture: TPicture;
  26. begin
  27.   Stream.Init(Data);
  28.   Picture.Init();
  29.  
  30.   try
  31.     Picture.LoadFromStream(Stream);
  32.     LoadFromTBitmap(Picture.GetBitmap());
  33.   finally
  34.     Picture.Free();
  35.     Stream.Free();
  36.   end;
  37. end;
  38.  
  39. procedure TRSItemImage.FromFile(FilePath: String);
  40. begin
  41.   if (Self = nil) then
  42.     Self.Init(Client.GetMBitmaps());
  43.  
  44.   LoadFromFile(FilePath);
  45. end;
  46.  
  47. procedure TRSItemImage.FromURL(URL: String);
  48. begin
  49.   if (Self = nil) then
  50.     Self.Init(Client.GetMBitmaps());
  51.  
  52.   FromData(GetPage(URL));
  53. end;
  54.  
  55. procedure TRSItemImage.FromGE(Identifer: String);
  56.  
  57.   function FindID: Int32;
  58.   const
  59.     URL = 'http://services.runescape.com/m=itemdb_oldschool/results';
  60.   var
  61.     Data: String;
  62.   begin
  63.     Data := GetPage(URL + '?query=' + LowerCase(Identifer));
  64.     Data := Between('class=''table-item-link''', '</a>', Data);
  65.  
  66.     Result := StrToIntDef(Between('obj=', '"', Data), -1);
  67.   end;
  68.  
  69.   function GetVersion: UInt64;
  70.   begin
  71.     Result := StrToUInt64Def(Between('<img src=''http://services.runescape.com/m=itemdb_oldschool/', '_obj_sprite.gif',
  72.                              GetPage('http://services.runescape.com/m=itemdb_oldschool/top100?list=1')), -1);
  73.     if (Result = -1) then
  74.       raise 'Unknown database version';
  75.   end;
  76.  
  77. var
  78.   ID: Int32;
  79. begin
  80.   ID := StrToIntDef(Identifer, -1);
  81.   if (ID = -1) then
  82.     ID := FindID();
  83.   if (ID = -1) then
  84.     raise 'Unknown item ID for "' + Identifer + '"';
  85.  
  86.   Self.FromURL(Format('http://services.runescape.com/m=itemdb_oldschool/%d_obj_sprite.gif?id=%d', [GetVersion(), ID]));
  87.   Self.ReplaceColor(16711935, 0);
  88. end;
  89.  
  90. procedure TRSItemImage.Align(Other: TRSItemImage);
  91. var
  92.   TPA1, TPA2: TPointArray;
  93.   P1, P2: TPoint;
  94.   BMP: TMufasaBitmap;
  95. begin
  96.   if Self.FindColors(TPA1, $10000) and Other.FindColors(TPA2, $10000) then
  97.   begin
  98.     TPA1.SortByRow(True);
  99.     TPA2.SortByRow(True);
  100.     P1 := TPA1[0];
  101.     P2 := TPA2[0];
  102.  
  103.     BMP := Self.Copy();
  104.     BMP.DrawTransparent(Max(0, P2.X - P1.X), Max(0, P2.Y - P1.Y), Self);
  105.     BMP.Free();
  106.  
  107.     Self.Crop(Abs(Min(0, P2.X - P1.X)), Abs(Min(0, P2.Y - P1.Y)), 31, 31);
  108.     Self.SetSize(32, 32);
  109.   end;
  110. end;
  111.  
  112. function TRSItemFinder.Get(Identifer: String): TRSItemImage;
  113. const
  114.   IMAGES_PATH = IncludePath + 'SRL/utils/items/';
  115. var
  116.   i: Int32;
  117. begin
  118.   for i := 0 to High(Self) do
  119.     if (Self[i].GetName() = Identifer) then
  120.       Exit(Self[i]);
  121.  
  122.   if FileExists(Identifer) then
  123.     Result.FromFile(Identifer)
  124.   else
  125.   if FileExists(IMAGES_PATH + Identifer + '.png') then
  126.     Result.FromFile(IMAGES_PATH + Identifer + '.png')
  127.   else
  128.   begin
  129.     Result.FromGE(Identifer);
  130.     Result.SaveToFile(IMAGES_PATH + Identifer + '.png');
  131.   end;
  132.  
  133.   Result.SetName(Identifer);
  134.  
  135.   if (Result.GetWidth() <> 32) or (Result.GetHeight() <> 32) then
  136.     raise 'Invaild image dimensions';
  137.  
  138.   Self += Result;
  139. end;
  140.  
  141. procedure TRSItemFinder.Free;
  142. var
  143.   i: Int32;
  144. begin
  145.   for i := 0 to High(Self) do
  146.     Self[i].Free();
  147. end;
  148.  
  149. function TRSItemFinder.Match(Img1, Img2: TMufasaBitmap;
  150.     Ignore1: TIntArray = IGNORE_COLORS_L;
  151.     Ignore2: TIntArray = IGNORE_COLORS_R;
  152.     HuePower: Double = 5.0): TRSItemMatch;
  153. var
  154.   i, off, Color1, Color2, Ignore, EdgeCount: Int32;
  155.   deltaH, H1, S1, L1, H2, S2, L2, Diff, Sum, EdgeDiff: Extended;
  156.   Data1, Data2: PRGB32;
  157.   DoIgnore: Boolean;
  158.   FACT := 1 / Sqrt(Sqr(100) + Sqr(100) + Sqr(50 * HuePower));
  159. begin
  160.   Data1 := Img1.GetData();
  161.   Data2 := Img2.GetData();
  162.   EdgeCount := 1;
  163.  
  164.   for i := 0 to Img1.GetWidth() * Img1.GetHeight() - 1 do
  165.   begin
  166.     Color1 := RGBToColor(Data1^.R, Data1^.G, Data1^.B);
  167.     Color2 := RGBToColor(Data2^.R, Data2^.G, Data2^.B);
  168.  
  169.     if (Ignore1.Find(Color1) = -1) and (Ignore2.Find(Color2) = -1) then
  170.     begin
  171.       RGBToHSL(Data1^.R, Data1^.G, Data1^.B, H1, S1, L1);
  172.       RGBToHSL(Data2^.R, Data2^.G, Data2^.B, H2, S2, L2);
  173.  
  174.       deltaH := Abs(H1 - H2);
  175.       if deltaH >= 50 then deltaH := 100 - deltaH;
  176.       deltaH *= HuePower;
  177.  
  178.       Diff := Sqrt(Sqr(deltaH) + Sqr(S1-S2) + Sqr(L1-L2)) * FACT;
  179.       Sum  := Sum + Diff;
  180.       if (Color1 = $10000) then
  181.       begin
  182.         if (Color2 = $10000) then
  183.           EdgeDiff := EdgeDiff + 1;
  184.         Inc(EdgeCount);
  185.       end;
  186.     end else
  187.       Inc(off);
  188.  
  189.     Inc(Data1); Inc(Data2);
  190.   end;
  191.  
  192.   if (Img1.GetWidth() * Img1.GetHeight() - off) = 0 then
  193.     Exit; // bad image
  194.   Result := [1 - sum / (Img1.GetWidth() * Img1.GetHeight() - off), EdgeDiff / EdgeCount];
  195. end;
  196.  
  197. function TRSItemFinder.FindAll(Identifer: String; Arr: TBoxArray; Similarity: Double = ITEM_FINDER_SIMILARITY): TIntegerArray;
  198. var
  199.   i, X, Y: Int32;
  200.   imgDB, imgRS: TRSItemImage;
  201.   Matches: array of TRSItemMatch;
  202.   Match, Best: TRSItemMatch;
  203. begin
  204.   SetLength(Matches, Length(Arr));
  205.  
  206.   for i := 0 to High(Arr) do
  207.     if FindColor(X, Y, $10000, Arr[i]) then // Has item
  208.     begin
  209.       imgDB := Self.Get(Identifer).Copy();
  210.       imgRS.FromClient(Arr[i].ExpandFunc(2));
  211.       imgRS.Align(imgDB);
  212.  
  213.       Match := Self.Match(imgDB, imgRS);
  214.       Matches[i] := Match;
  215.       if (Match.Item >= Best.Item) then
  216.         Best := Match;
  217.  
  218.       imgDB.Free();
  219.       imgRS.Free();
  220.     end;
  221.  
  222.   for i := 0 to High(Arr) do
  223.     if (Matches[i] >= Similarity) and (Matches[i].Item >= Best.Item - 0.01) then
  224.       Result += i;
  225. end;
  226.  
  227. // ------------------------------ Inventory --------------------------------- \\
  228.  
  229. // Indices of all matches
  230. function TRSInventory.FindAll(Identifers: TStringArray; Similarity: Double = ITEM_FINDER_SIMILARITY): TIntegerArray; overload;
  231. var
  232.   Identifer: String;
  233. begin
  234.   if Self.Open() then
  235.     for Identifer in Identifers do
  236.       Result += ItemFinder.FindAll(Identifer, Self.FSlots, Similarity);
  237. end;
  238.  
  239. function TRSInventory.FindAll(Identifer: String; Similarity: Double = ITEM_FINDER_SIMILARITY): TIntegerArray; overload;
  240. begin
  241.   Result := Self.FindAll([Identifer]);
  242. end;
  243.  
  244. // Index of first match
  245. function TRSInventory.Find(Identifers: TStringArray; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32; overload;
  246. var
  247.   Identifer: String;
  248.   Matches: TIntegerArray;
  249. begin
  250.   for Identifer in Identifers do
  251.   begin
  252.     Matches := Self.FindAll(Identifer, Similarity);
  253.     if Length(Matches) > 0 then
  254.       Exit(Matches[0]);
  255.   end;
  256.  
  257.   Exit(-1);
  258. end;
  259.  
  260. function TRSInventory.Find(Identifer: String; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32; overload;
  261. begin
  262.   Result := Self.Find([Identifer]);
  263. end;
  264.  
  265. // Counts all items
  266. function TRSInventory.Count(Identifers: TStringArray; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32; overload;
  267. var
  268.   Identifer: String;
  269. begin
  270.   for Identifer in Identifers do
  271.     Result += Length(Self.FindAll(Identifer, Similarity));
  272. end;
  273.  
  274. // Counts a item
  275. function TRSInventory.Count(Identifer: String; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32; overload;
  276. begin
  277.   Result := Self.Count([Identifer], Similarity);
  278. end;
  279.  
  280. // Counts a item stack
  281. function TRSInventory.CountStack(Identifer: String; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32;
  282. var
  283.   Slot: Int32;
  284. begin
  285.   Slot := Self.Find(Identifer, Similarity);
  286.   if (Slot > -1) then
  287.     Result := srl.GetItemAmount(Self.GetSlotBox(Slot));
  288. end;
  289.  
  290. // Clicks first item match
  291. function TRSInventory.Click(Identifers: TStringArray; Option: String = ''; Similarity: Double = ITEM_FINDER_SIMILARITY): Boolean; overload;
  292. var
  293.   Slot: Int32;
  294. begin
  295.   Slot := Self.Find(Identifers, Similarity);
  296.  
  297.   if (Slot > -1) then
  298.   begin
  299.     Self.MouseSlot(Slot, mouse_Move);
  300.  
  301.     if (Option = '') then
  302.       Mouse.Click(mouse_Left)
  303.     else
  304.     if (not ChooseOption.Open()) or (not ChooseOption.Select(Option)) then
  305.       Exit(False);
  306.  
  307.     Exit(True);
  308.   end;
  309. end;
  310.  
  311. function TRSInventory.Click(Identifer: String; Option: String = ''; Similarity: Double = ITEM_FINDER_SIMILARITY): Boolean; overload;
  312. begin
  313.   Result := Self.Click([Identifer], Option, Similarity);
  314. end;
  315.  
  316. // -------------------------------- Bank ------------------------------------ \\
  317.  
  318. // Index of first match
  319. function TRSBankScreen.Find(Identifers: TStringArray; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32; overload;
  320. var
  321.   Identifer: String;
  322.   Matches: TIntegerArray;
  323. begin
  324.   Self.FixSlots();
  325.  
  326.   for Identifer in Identifers do
  327.   begin
  328.     Matches := ItemFinder.FindAll(Identifer, Self.FSlots, Similarity);
  329.     if Length(Matches) > 0 then
  330.       Exit(Matches[0]);
  331.   end;
  332.  
  333.   Exit(-1);
  334. end;
  335.  
  336. function TRSBankScreen.Find(Identifer: String; Similarity: Double = ITEM_FINDER_SIMILARITY): Int32; overload;
  337. begin
  338.   Result := Self.Find([Identifer]);
  339. end;
  340.  
  341. // Withdraw first match
  342. function TRSBankScreen.Withdraw(Identifier: String; Amount: Int32; Mode: EBankButton = bbItem): Boolean; overload;
  343. var
  344.   Slot: Int32;
  345. begin
  346.   Slot := Self.Find(Identifier);
  347.   if (Slot > -1) then
  348.     Result := Self.Withdraw(Slot, Amount, TStringArray([]), Mode);
  349. end;
  350.  
  351. // Contains
  352. function TRSBankScreen.Contains(Identifer: String): Boolean;
  353. begin
  354.   Result := Self.Find(Identifer) >= 0;
  355. end;
  356.  
  357. // Counts a item stack
  358. function TRSBankScreen.CountStack(Identifer: String): Int32;
  359. var
  360.   Slot: Int32;
  361. begin
  362.   Slot := Self.Find(Identifer);
  363.   if (Slot > -1) then
  364.     Result := srl.GetItemAmount(Self.GetSlotBox(Slot));
  365. end;
  366.  
  367. begin
  368.   AddOnTerminate(@ItemFinder.Free);
  369.   (*
  370.   SetTargetBitmap(LoadBitmap('Images/client.png'));
  371.   WriteLn Bankscreen.Find('mind rune');
  372.   *)
  373. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement