· last year · Sep 15, 2024, 05:10 PM
1program new;
2{$DEFINE SRL_USE_REMOTEINPUT}
3{$I SRL/osr.simba}
4
5var
6 NativeClient: PtrInt;
7 RSW: TRSWalker;
8
9// -----------------------------------------------------------------------------
10// -----------------------------------------------------------------------------
11// WIN API stuff
12
13const WINAPI_CC = {$IFDEF CPU386}' stdcall'{$ELSE}' win64'{$ENDIF};
14const ffi_winapi = {$IFDEF CPU386}ffi_stdcall{$ELSE}ffi_win64{$ENDIF};
15
16type
17 _EnumWindowsProc = function(wnd:DWORD; Param:Pointer): LongBool;
18 TEnumWindowsProc = native(_EnumWindowsProc, ffi_winapi);
19
20function GetAsyncKeyState(vKey: Int32): Int16; external 'GetAsyncKeyState@user32.dll' + WINAPI_CC;
21function GetForegroundWindow(): PtrUInt; external 'GetForegroundWindow@user32.dll' + WINAPI_CC;
22function GetWindowThreadProcessId(wnd: PtrUInt; out dwProcessId: DWORD): DWORD; external 'GetWindowThreadProcessId@user32.dll' + WINAPI_CC;
23function EnumChildWindows(hWndParent: DWORD; func: TEnumWindowsProc; Param: Pointer): LongBool; external 'EnumChildWindows@user32.dll' + WINAPI_CC;
24
25function GetKeyDown(): Char;
26var
27 key: Word;
28 keys: array of Word;
29begin
30 keys := [VK_A..VK_Z];
31 keys += [VK_0..VK_9];
32 keys += [VK_OEM_PERIOD, VK_OEM_MINUS]; //add more keys if you need
33 for Key in keys do
34 if GetAsyncKeyState(key) and $8000 <> 0 then
35 begin
36 while GetAsyncKeyState(key) and $8000 <> 0 do Wait(10);
37 if key = VK_OEM_PERIOD then key := Ord('.');
38 if key = VK_OEM_MINUS then key := Ord('-');
39 Exit(Char(key));
40 end;
41end;
42
43function IsKeyDown2(vKey: Word): Boolean;
44begin
45 Result := GetAsyncKeyState(vKey) and $8000 <> 0;
46end;
47
48function GetRSAppletWnd(PID: DWORD): DWORD;
49 function GetLastChild(Handle: DWORD; Param: Pointer): LongBool; static;
50 begin
51 if handle <> 0 then
52 begin
53 DWORD(Param^) := handle;
54 Result := True;
55 end;
56 end;
57var
58 p: TSysProc;
59 client: DWORD;
60begin
61 for p in GetProcesses() do
62 if p.Pid = PID then
63 Break;
64 EnumChildWindows(p.Handle, @GetLastChild, @Result);
65 if Result = 0 then
66 Result := NativeClient;
67end;
68
69
70
71
72// ---------
73// ---------
74// ---------
75
76function WorldToMSTile(Me, ObjLoc: TPoint; Height:Double=0; Offx,Offy:Double=0): TRectangle;
77var
78 Angle: Double;
79begin
80 ObjLoc := Point(Minimap.Center.X, Minimap.Center.Y) + (ObjLoc - Me);
81 Angle := Minimap.GetCompassAngle(False);
82 ObjLoc := ObjLoc.Rotate(Angle, Point(Minimap.Center.X, Minimap.Center.Y));
83 Result := Minimap.VecToMSRect(Vec3(ObjLoc.x - offx, ObjLoc.y - offy, Height), Angle);
84end;
85
86procedure Setup();
87var
88 r: String;
89 DefaultBox: TBox = [75,40, 425,140];
90 client2: TClient;
91
92type
93 TButtonBox = record
94 TextTPA: TPointArray;
95 Bounds: TBox;
96 end;
97
98 procedure WaitReleaseMouse(key:Int32);
99 begin
100 while client2.GetIOManager.IsMouseButtonDown(key) do Wait(10);
101 end;
102
103 function GetClick(out p: TPoint): Boolean;
104 begin
105 if not EIOS_HasFocus(RSClient.RemoteInput.EIOS) then Exit();
106
107 if client2.GetIOManager.IsMouseButtonDown(1) then
108 begin
109 client2.GetIOManager.GetMousePos(p.x,p.y);
110 Result := p.InBox(GetClientBounds);
111 WaitReleaseMouse(1);
112 end;
113 end;
114
115 function GetButton(txt: String): TButtonBox;
116 begin
117 Result.TextTPA := TPAFromText(txt, 'StatChars07');
118 Result.Bounds := GetTPABounds(Result.TextTPA).Expand(8);
119 end;
120
121 function DrawButton(p: TPoint; var Button: TButtonBox): TButtonBox;
122 var tmp: TButtonBox;
123 begin
124 Button.TextTPA := Button.TextTPA.Offset(p);
125 Button.Bounds := Button.Bounds.Offset(p);
126 RSClient.Image.DrawBoxFilled(Button.Bounds, False, 2502198);
127 RSClient.Image.DrawBoxFilled(Button.Bounds.Expand(-1), False, 4607315);
128 RSClient.Image.DrawTPA(Button.TextTPA, $FFFFFF);
129 end;
130
131 function MessageBox(Text: String; Area:TBox=[]): string;
132 var
133 xstart: Int32;
134 TPA: TPointArray;
135 box: TBox;
136 begin
137 if (Area.x1 = Area.x2) then Area := chat.Bounds();
138 RSClient.Image.DrawBox(Area.Expand(-0), $1F2F33);
139 RSClient.Image.DrawBox(Area.Expand(-1), $3F4A5A);
140 RSClient.Image.DrawBox(Area.Expand(-2), $1F2F33);
141 RSClient.Image.DrawBoxFilled(Area.Expand(-3), False, $171D20);
142
143 TPA := TPAFromText(Text, 'SmallChars07');
144 box := GetTPABounds(TPA);
145 xstart := (box.Width + Area.Width) div 2 - box.Width;
146 OffsetTPA(TPA, Point(Area.x1+xstart, Area.y1+20));
147 RSClient.Image.DrawTPA(TPA, $FFFFFF);
148 end;
149
150 function Query(Text: String; Alts:TStringArray; Area:TBox=[]): string;
151 var
152 i,xstart,CurrWidth: Int32;
153 p: TPoint;
154 Buttons: array of TButtonBox;
155 xOffset: TIntegerArray;
156 begin
157 if (Area.x1 = Area.x2) then Area := chat.Bounds;
158
159 // query
160 MessageBox(Text, Area);
161
162 // buttons
163 for i:=0 to High(Alts) do
164 begin
165 Buttons += GetButton(Alts[i]);
166 xOffset += CurrWidth;
167 CurrWidth += Buttons[i].Bounds.X2+20;
168 end;
169 CurrWidth -= 20;
170
171 xstart := (CurrWidth + Area.Width) div 2 - CurrWidth;
172 for i:=0 to High(Buttons) do
173 begin
174 DrawButton(Point(Area.x1+xstart+xOffset[i], Area.y1+50), Buttons[i]);
175 end;
176
177 // handling
178 while True do
179 begin
180 if GetClick(p) then
181 begin
182 for i:=0 to High(Buttons) do
183 if PointInBox(p, Buttons[i].Bounds) then
184 begin
185 RSClient.Image.DrawBoxFilled(Area, False, 0);
186 Exit(Alts[i]);
187 end;
188 end;
189 Wait(1);
190 end;
191 end;
192
193 function QueryStr(Text: String; Area:TBox=[]): string;
194 var
195 i: Int32;
196 pt, p: TPoint;
197 chr: Char;
198 B: TBox;
199 TPA: TPointArray;
200 Button: TButtonBox;
201 textArea: Tbox;
202 begin
203 if (Area.x1 = Area.x2) then
204 Area := Chat.Bounds;
205
206 // query
207 RSClient.Image.DrawBox(Area.Expand(-0), $1F2F33);
208 RSClient.Image.DrawBox(Area.Expand(-1), $3F4A5A);
209 RSClient.Image.DrawBox(Area.Expand(-2), $1F2F33);
210 RSClient.Image.DrawBoxFilled(Area.Expand(-3), False, $171D20);
211
212 TPA := TPAFromText(Text, 'SmallChars07');
213 OffsetTPA(TPA, Point(Area.x1+40, Area.y1+20));
214 RSClient.Image.DrawTPA(TPA, $FFFFFF);
215 B := GetTPABounds(TPA);
216
217 // button
218 Button := GetButton('OK');
219 DrawButton(Point(Area.x1+48, Area.y1+50), Button);
220
221 // handling
222 pt.x := B.x2+5;
223 pt.y := Area.y1+25;
224 repeat
225 while not EIOS_HasFocus(RSClient.RemoteInput.EIOS) do Wait(10);
226
227 if GetClick(p) then
228 if PointInBox(p, Button.Bounds) then
229 begin
230 RSClient.Image.DrawBoxFilled(Area, False, 0);
231 Exit(Result);
232 end;
233
234 chr := GetKeyDown();
235 if chr <> #0 then
236 begin
237 Result += Lowercase(chr);
238 PressKey(VK_BACK); //ensure deletion if bugged input blocking
239 RSClient.Image.DrawText(Result, pt, $FFCCAA);
240 end;
241
242 if IsKeyDown2(VK_BACK) and (Result <> '') then
243 begin
244 textArea := [pt.X, pt.y, RSClient.Image.TextWidth(Result)+pt.x, RSClient.Image.TextHeight(Result)+pt.y];
245 RSClient.Image.DrawBoxFilled(textArea, False, $171D20);
246 while IsKeyDown2(VK_BACK) do Wait(50);
247 SetLength(Result, Length(Result)-1);
248 RSClient.Image.DrawText(Result, pt, $FFCCAA);
249 end;
250 until False;
251 end;
252
253 function SetupLocations(): TPointArray;
254 var
255 p, me, worldPt: TPoint;
256 rect: TRectangle;
257 begin
258 me := RSW.GetMyPos();
259
260 while True do
261 begin
262 if GetClick(p) then
263 begin
264 worldPt := (MainScreen.PointToMM(p).ToPoint() - Point(Minimap.Center.X, Minimap.Center.Y)) + me;
265
266 Mouse.Move(p);
267 Sleep(100);
268 WriteLn('Uptext recorded: ', MainScreen.GetUpText().Before('/'));
269
270 rect := WorldToMSTile(me, worldPt);
271 if Mainscreen.Bounds.Contains(rect.Bounds) then
272 begin
273 RSClient.Image.DrawRect(rect, $FFFF);
274 case Query('Are you happy?', ['Add more', 'Retry', 'Yes']) of
275 'Retry': RSClient.Image.DrawRect(rect, 0);
276 'Add more': Result += worldPt;
277 'Yes': begin Result += worldPt; Break; end;
278 end;
279 end;
280 end;
281 Wait(1);
282 end;
283 RSClient.Image.Clear();
284 end;
285
286label
287 START, QUERY_CONFIG;
288
289begin
290 client2.Init(PluginPath);
291 client2.GetIOManager.SetTarget2(GetRSAppletWnd(RSClient.RemoteInput.PID));
292
293 RSClient.Image.setFontSize(10);
294 RSClient.Image.setFontAntialiasing(False);
295
296START:
297 r := Query('Do you wish to run setup?', ['Yes','No'], DefaultBox);
298 WriteLn(r);
299
300
301 r := MessageBox('Preparing, please stand by...', DefaultBox);
302 minimap.SetCompassAngle(0);
303 RSW.Setup('world');
304
305 Query('Click the rocks you wish to mine...', ['OK'], DefaultBox);
306 WriteLn SetupLocations();
307
308 Writeln QueryStr('Save config as: ', DefaultBox);
309
310
311 client2.Free();
312end;
313
314
315
316
317begin
318 NativeClient := GetNativeWindow();
319
320 if EIOS_IsMouseInputEnabled(RSClient.RemoteInput.EIOS) then
321 EIOS_SetMouseInputEnabled(RSClient.RemoteInput.EIOS, False);
322 if EIOS_IsKeyboardInputEnabled(RSClient.RemoteInput.EIOS) then
323 EIOS_SetKeyboardInputEnabled(RSClient.RemoteInput.EIOS, False);
324
325 Setup();
326
327 EIOS_SetMouseInputEnabled(RSClient.RemoteInput.EIOS, True);
328 EIOS_SetKeyboardInputEnabled(RSClient.RemoteInput.EIOS, True);
329end.