Jump to content
shadowrecon

Making my own client -> Help =/

Recommended Posts

Ok, so over the last few days ive been messing around with delphi, ive been playing with this idea of making my own client just as a toy/learning process. Ive managed to add functions and get it to compile scripts but i cant figure out how to get the pre-processor to check for defines and load them. Since im using PascalScript i figured freddy or someone else might have an idea. here is my code:

 

[scar]

unit Shadows_Client;

 

interface

 

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

ExtCtrls, StdCtrls, uPSCompiler, uPSRuntime,uPSPreprocessor,

Menus, uPSC_comobj, uPSR_comobj, uPSComponent, uPSComponent_StdCtrls,

uPSComponent_Controls, uPSComponent_Forms, uPSComponent_DB, uPSComponent_COM,

uPSComponent_Default;

 

type

TUB_SE = class(TForm)

PSScript1: TPSScript;

MainMenu1: TMainMenu;

File1: TMenuItem;

Open1: TMenuItem;

Save1: TMenuItem;

Exit1: TMenuItem;

Script1: TMenuItem;

Stop1: TMenuItem;

Compile1: TMenuItem;

Edit1: TMenuItem;

ClearDebug1: TMenuItem;

Update1: TMenuItem;

UpdateNow1: TMenuItem;

LBLDebug: TLabel;

LBLCode: TLabel;

LBLFuncList: TLabel;

PSScriptDebugger1: TPSScriptDebugger;

PSDllPlugin1: TPSDllPlugin;

PSImport_Classes1: TPSImport_Classes;

PSImport_DateUtils1: TPSImport_DateUtils;

PSImport_ComObj1: TPSImport_ComObj;

PSImport_DB1: TPSImport_DB;

PSImport_Forms1: TPSImport_Forms;

PSImport_Controls1: TPSImport_Controls;

PSImport_StdCtrls1: TPSImport_StdCtrls;

PSCustomPlugin1: TPSCustomPlugin;

Debug: TMemo;

Code: TMemo;

FuncList: TMemo;

SaveAs1: TMenuItem;

CompileWTimer1: TMenuItem;

OpenDialog1: TOpenDialog;

SaveDialog1: TSaveDialog;

New1: TMenuItem;

procedure IFPS3ClassesPlugin1CompImport(Sender: TObject;

Imp: TIFPSPascalcompiler);

procedure IFPS3ClassesPlugin1ExecImport(Sender: TObject; Exec: TIFPSExec;

Imp: TIFPSRuntimeClassImporter);

procedure Open1Click(Sender: TObject);

procedure Save1Click(Sender: TObject);

procedure SaveAs1Click(Sender: TObject);

procedure New1Click(Sender: TObject);

procedure Exit1Click(Sender: TObject);

procedure Compile1Click(Sender: TObject);

procedure Stop1Click(Sender: TObject);

procedure CompileWTimer1Click(Sender: TObject);

procedure ClearDebug1Click(Sender: TObject);

private

fn: string;

changed: Boolean;

function SaveTest: Boolean;

public

{ Public declarations }

end;

 

var

UB_SE: TUB_SE;

 

implementation

 

uses

uPSC_dll, uPSR_dll, uPSDebugger,

uPSR_std, uPSC_std, uPSR_stdctrls, uPSC_stdctrls,

uPSR_forms, uPSC_forms,

uPSC_graphics,

uPSC_controls,

uPSC_classes,

uPSR_graphics,

uPSR_controls,

uPSR_classes;

 

{$R *.DFM}

 

var

Imp: TPSRuntimeClassImporter;

 

procedure TUB_SE.IFPS3ClassesPlugin1CompImport(Sender: TObject;

Imp: TIFPSPascalcompiler);

begin

SIRegister_Std(Imp);

SIRegister_Classes(Imp, true);

SIRegister_Graphics(Imp, true);

SIRegister_Controls(Imp);

SIRegister_stdctrls(Imp);

SIRegister_Forms(Imp);

SIRegister_ComObj(Imp);

end;

 

procedure TUB_SE.IFPS3ClassesPlugin1ExecImport(Sender: TObject; Exec: TIFPSExec;

Imp: TIFPSRuntimeClassImporter);

begin

RIRegister_Std(Imp);

RIRegister_Classes(Imp, True);

RIRegister_Graphics(Imp, True);

RIRegister_Controls(Imp);

RIRegister_stdctrls(Imp);

RIRegister_Forms(Imp);

RIRegister_ComObj(exec);

end;

 

function StringLoadFile(const Filename: string): string;

var

Stream: TStream;

begin

Stream := TFileStream.Create(Filename, fmOpenread or fmSharedenywrite);

try

SetLength(Result, Stream.Size);

Stream.Read(Result[1], Length(Result));

finally

Stream.Free;

end;

end;

 

function OnNeedFile(Sender: TPSPreProcessor; const callingfilename: AnsiString; var FileName, Output: AnsiString): Boolean;

var

s: string;

begin

s := ExtractFilePath(callingfilename);

if s = '' then s := ExtractFilePath(Paramstr(0));

Filename := s + Filename;

if FileExists(Filename) then

begin

Output := StringLoadFile(Filename);

Result := True;

end else

Result := False;

end;

 

procedure TUB_SE.Save1Click(Sender: TObject);

begin

if fn = '' then

begin

Saveas1Click(nil);

end

else

begin

Code.Lines.SaveToFile(fn);

Debug.Lines.Clear;

changed := False;

end;

end;

 

procedure TUB_SE.SaveAs1Click(Sender: TObject);

begin

SaveDialog1.FileName := '';

if SaveDialog1.Execute then

begin

fn := SaveDialog1.FileName;

Code.Lines.SaveToFile(fn);

Debug.Lines.Clear;

changed := False;

end;

end;

 

function TUB_SE.SaveTest: Boolean;

begin

if changed then

begin

case MessageDlg('File is not saved, save now?', mtWarning, mbYesNoCancel, 0) of

mrYes:

begin

Save1Click(nil);

Result := not changed;

end;

mrNo: Result := True;

else

Result := False;

end;

end

else

Result := True;

end;

 

procedure TUB_SE.Stop1Click(Sender: TObject);

begin

if tag <> 0 then

TPSExec(tag).Stop;

end;

 

Procedure MyWait(T: Integer);

begin

Sleep(T);

end;

 

function MyWriteln(Caller: TPSExec; p: TIFExternalProcRec; Global, Stack: TPSStack): Boolean;

var

PStart: Cardinal;

begin

if Global = nil then begin result := false; exit; end;

PStart := Stack.Count - 1;

UB_SE.Debug.Lines.Add(Stack.GetString(PStart));

Result := True;

end;

 

function MyReadln(Caller: TPSExec; p: TIFExternalProcRec; Global, Stack: TPSStack): Boolean;

var

PStart: Cardinal;

begin

if Global = nil then begin result := false; exit; end;

PStart := Stack.Count - 2;

Stack.SetString(PStart + 1, InputBox(UB_SE.Caption, Stack.GetString(PStart), ''));

Result := True;

end;

 

Function MyCountColor(Color, Xs,Ys,Xe,Ye: Integer; DC : Cardinal): Integer;

Var

Canvas : TCanvas;

I, J : Integer;

Begin

Result := 0;

Canvas := TCanvas.Create;

Canvas.Handle := DC;

For I := Xs to Xe Do

For J := Ys to Ye Do

If Canvas.Pixels[i, J] = Color Then

Inc(Result);

Canvas.Free;

End;

 

function MyOnUses(Sender: TPSPascalCompiler; const Name: AnsiString): Boolean;

begin

if Name = 'SYSTEM' then

begin

TPSPascalCompiler(Sender).AddFunction('procedure Writeln(s: string);');

TPSPascalCompiler(Sender).AddFunction('function Readln(question: string): string;');

Sender.AddDelphiFunction('Function CountColor(Color, Xs,Ys,Xe,Ye: Integer; DC : Cardinal): Integer;');

 

Sender.AddConstantN('NaN', 'extended').Value.textended := 0.0 / 0.0;

Sender.AddConstantN('Infinity', 'extended').Value.textended := 1.0 / 0.0;

Sender.AddConstantN('NegInfinity', 'extended').Value.textended := - 1.0 / 0.0;

 

SIRegister_Std(Sender);

SIRegister_Classes(Sender, True);

SIRegister_Graphics(Sender, True);

SIRegister_Controls(Sender);

SIRegister_stdctrls(Sender);

SIRegister_Forms(Sender);

SIRegister_ComObj(Sender);

 

AddImportedClassVariable(Sender, 'Code', 'TMemo');

AddImportedClassVariable(Sender, 'Debug', 'TMemo');

AddImportedClassVariable(Sender, 'Self', 'TForm');

AddImportedClassVariable(Sender, 'Application', 'TApplication');

 

Result := True;

end

else

begin

TPSPascalCompiler(Sender).MakeError('', ecUnknownIdentifier, '');

Result := False;

end;

end;

 

var

IgnoreRunline: Boolean = False;

I: Integer;

 

procedure RunLine(Sender: TPSExec);

begin

if IgnoreRunline then Exit;

i := (i + 1) mod 15;

Sender.GetVar('');

if i = 0 then Application.ProcessMessages;

end;

 

function MyExportCheck(Sender: TPSPascalCompiler; Proc: TPSInternalProcedure; const ProcDecl: AnsiString): Boolean;

begin

Result := True;

end;

 

procedure TUB_SE.ClearDebug1Click(Sender: TObject);

begin

Debug.Lines.Clear;

Debug.Lines.Add('Https://www.UnitedBots.Net'#13#10'Scripted By: ShadowRecon.');

end;

 

procedure TUB_SE.Compile1Click(Sender: TObject);

var

x1: TPSPascalCompiler;

x2: TPSDebugExec;

xpre: TPSPreProcessor;

s, d: AnsiString;

 

procedure Outputtxt(const s: string);

begin

Debug.Lines.Add(s);

end;

 

procedure OutputMsgs;

var

l: Longint;

b: Boolean;

begin

b := False;

for l := 0 to x1.MsgCount - 1 do

begin

Outputtxt(x1.Msg[l].MessageToString);

if (not b) and (x1.Msg[l] is TPSPascalCompilerError) then

begin

b := True;

Code.SelStart := X1.Msg[l].Pos;

end;

end;

end;

 

begin

if tag <> 0 then exit;

Debug.Clear;

xpre := TPSPreProcessor.Create;

try

xpre.OnNeedFile := OnNeedFile;

xpre.MainFileName := fn;

xpre.MainFile := Code.Text;

xpre.PreProcess(xpre.MainFileName, s);

 

x1 := TPSPascalCompiler.Create;

x1.OnExportCheck := MyExportCheck;

x1.OnUses := MyOnUses;

x1.OnExternalProc := DllExternalProc;

x1.AllowNoEnd := true;

if x1.Compile(s) then

begin

Outputtxt('Succesfully compiled');

xpre.AdjustMessages(x1);

OutputMsgs;

if not x1.GetOutput(s) then

begin

x1.Free;

Outputtxt('[Error] : Could not get data');

exit;

end;

x1.GetDebugOutput(d);

x1.Free;

x2 := TPSDebugExec.Create;

try

RegisterDLLRuntime(x2);

RegisterClassLibraryRuntime(x2, Imp);

RIRegister_ComObj(x2);

 

tag := longint(x2);

if sender <> nil then

x2.OnRunLine := RunLine;

 

x2.RegisterFunctionName('WRITELN', MyWriteln, nil, nil);

x2.RegisterFunctionName('READLN', MyReadln, nil, nil);

x2.RegisterDelphiFunction(@MyCountColor, 'COUNTCOLOR', cdRegister);

 

if not x2.LoadData(s) then

begin

Outputtxt('[Error] : Could not load data: '+TIFErrorToString(x2.ExceptionCode, x2.ExceptionString));

tag := 0;

exit;

end;

x2.LoadDebugData(d);

SetVariantToClass(x2.GetVarNo(x2.GetVar('Code')), Code);

SetVariantToClass(x2.GetVarNo(x2.GetVar('Debug')), Debug);

SetVariantToClass(x2.GetVarNo(x2.GetVar('SELF')), Self);

SetVariantToClass(x2.GetVarNo(x2.GetVar('APPLICATION')), Application);

 

x2.RunScript;

if x2.ExceptionCode <> erNoError then

Outputtxt('[Runtime Error] : ' + TIFErrorToString(x2.ExceptionCode, x2.ExceptionString) +

' in ' + IntToStr(x2.ExceptionProcNo) + ' at ' + IntToSTr(x2.ExceptionPos))

else

OutputTxt('Successfully executed');

finally

tag := 0;

x2.Free;

end;

end

else

begin

Outputtxt('Failed when compiling');

xpre.AdjustMessages(x1);

OutputMsgs;

x1.Free;

end;

finally

Xpre.Free;

end;

end;

 

procedure TUB_SE.CompileWTimer1Click(Sender: TObject);

var

Freq, Time1, Time2: Comp;

begin

if not QueryPerformanceFrequency(TLargeInteger((@Freq)^)) then

begin

ShowMessage('Your computer does not support Performance Timers!');

exit;

end;

QueryPerformanceCounter(TLargeInteger((@Time1)^));

IgnoreRunline := True;

try

Compile1Click(nil);

except

end;

IgnoreRunline := False;

QueryPerformanceCounter(TLargeInteger((@Time2)^));

Debug.Lines.Add('Time: ' + Sysutils.FloatToStr((Time2 - Time1) / Freq) +

' sec');

end;

 

procedure TUB_SE.Exit1Click(Sender: TObject);

begin

Close;

end;

 

procedure TUB_SE.New1Click(Sender: TObject);

begin

if not SaveTest then

exit;

Code.Lines.Text := 'Program New;'#13#10'Begin'#13#10'End.';

Debug.Lines.Clear;

Debug.Lines.Add('Https://www.UnitedBots.Net'#13#10'Scripted By: ShadowRecon.');

fn := '';

end;

 

procedure TUB_SE.Open1Click(Sender: TObject);

begin

if not SaveTest then

exit;

if OpenDialog1.Execute then

begin

Code.Lines.LoadFromFile(OpenDialog1.FileName);

changed := False;

debug.Lines.Clear;

FuncList.Lines.Clear;

fn := OpenDialog1.FileName;

end;

end;

end.

[/scar]

Link to comment
Share on other sites

There is a function somewhere in there to add defines... SCAR has it's own custom preprocessor, so I don't remember what function exactly it was in PascalScript. Howeve,r I don't really see what you're trying to achieve... (Not that I want to discourage you trying new things.)

Link to comment
Share on other sites

There is a function somewhere in there to add defines... SCAR has it's own custom preprocessor, so I don't remember what function exactly it was in PascalScript. Howeve,r I don't really see what you're trying to achieve... (Not that I want to discourage you trying new things.)

 

I just wanted to play around with it. It will prob go no further than it has I got my enjoy meant out of writelning and readlning.. lol. the main goal to to create a platform to build exe's from my scripts but i need source code to do this. I was originally going to make a simple C++ console app to run the cmd commands to open scar / run script ect but i could not get the commands to work so i started messing around with this.

 

---------- Post added at 01:15 PM ---------- Previous post was at 10:17 AM ----------

 

Is it possible to open SMART outside of scar/simba? I managed to include the SMART.dll file, and ive extracted the functions but when i run the code i get the error from smart saying

"SMART ...Target not set ect.." Heres my code

Unit Code:

[scar]

unit Unit1;

 

interface

 

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

 

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

 

var

Form1: TForm1;

procedure SmartSetup(root, params: String; width, height: Integer; initseq: String); stdcall;

procedure SmartSetJVMPath(path: String); stdcall;

procedure SmartSetMaxJVMMem(mb: integer); stdcall;

procedure SmartSetUserAgent(useragent: String); stdcall;

 

implementation

 

{$R *.dfm}

 

procedure SmartSetup; external 'SMART.dll' name 'std_setup';

procedure SmartSetJVMPath; external 'SMART.dll' name 'std_setJVMPath';

procedure SmartSetMaxJVMMem; external 'SMART.dll' name 'std_setMaxJVMMem';

procedure SmartSetUserAgent; external 'SMART.dll' name 'std_setUserAgent';

 

procedure TForm1.Button1Click(Sender: TObject);

begin

SmartSetup('http://world11.runescape.com/', ',f5', 765, 503, 'S');

end;

 

end.

[/scar]

 

Source Code:

[scar]

program Project2;

 

 

 

uses

Forms,

Windows,

Classes,

SysUtils,

Unit1 in 'Unit1.pas' {Form1};

 

{$R *.res}

{$R '..\..\..\..\Desktop\smartdll.RES'}

 

var

rStream: TResourceStream;

fStream: TFileStream;

fname: string;

sAppPath : string;

begin

Application.Initialize;

Application.MainFormOnTaskbar := True;

 

sAppPath:=IncludeTrailingPathDelimiter

(ExtractFileDir(Application.ExeName));

if not FileExists(sAppPath +'SMART.dll') then

begin

fname:=sAppPath+'SMART.dll';

rStream := TResourceStream.Create

(hInstance, 'SMART', RT_RCDATA);

try

fStream := TFileStream.Create(fname, fmCreate);

try

fStream.CopyFrom(rStream, 0);

finally

fStream.Free;

end;

finally

rStream.Free;

end;

end;

 

SmartSetMaxJVMMem(100);

Application.CreateForm(TForm1, Form1);

Application.Run;

end.

[/scar]

Link to comment
Share on other sites

Perhaps if you look in Smart.scar.

 

I think you miss a function call : SetTargetDC

 

[sCAR]

{=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

procedure SmartSetTarget;

Contributors: BenLand100, Wanted.

Description: Makes SMART SCAR's canvas target.

Date Created: Unknown Date. By BenLand100. RS2 Build Unknown.

Last Modification: October 30th, 2011. By Wanted. RS2 Build 671.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}

 

procedure SmartSetTarget;

var

Smart_Bitmap: Integer;

begin

Smart_Bitmap:= BitmapFromString(RSPW - 1, RSPH - 1, '');

GetBitmapCanvas(Smart_Bitmap).Handle:= SmartGetDC;

SetTargetBitmap(Smart_Bitmap);

FreeBitmap(Smart_Bitmap);

end;

 

{=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

function InitiateSMART: Boolean;

Contributors: Wanted

Description: Initiates SMART more simply.

Date Created: September 18th, 2011. By Wanted. RS2 Build 666.

Last Modification: November 21st, 2011. By Wanted. RS2 Build 681.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}

 

function InitiateSMART: Boolean;

begin

Result := False;

if (SMART_Server = 0) then

SMART_Server := 11;

if (not (SmartSetupEx(SMART_Server, True))) then

Exit;

SetTargetDC(SmartGetDC);

Result := WaitFunc(@RSReady, True, 100, 250, 90000, 120000);

end;

[/sCAR]

Link to comment
Share on other sites

Perhaps if you look in Smart.scar.

 

I think you miss a function call : SetTargetDC

 

[sCAR]

{=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

procedure SmartSetTarget;

Contributors: BenLand100, Wanted.

Description: Makes SMART SCAR's canvas target.

Date Created: Unknown Date. By BenLand100. RS2 Build Unknown.

Last Modification: October 30th, 2011. By Wanted. RS2 Build 671.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}

 

procedure SmartSetTarget;

var

Smart_Bitmap: Integer;

begin

Smart_Bitmap:= BitmapFromString(RSPW - 1, RSPH - 1, '');

GetBitmapCanvas(Smart_Bitmap).Handle:= SmartGetDC;

SetTargetBitmap(Smart_Bitmap);

FreeBitmap(Smart_Bitmap);

end;

 

{=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

function InitiateSMART: Boolean;

Contributors: Wanted

Description: Initiates SMART more simply.

Date Created: September 18th, 2011. By Wanted. RS2 Build 666.

Last Modification: November 21st, 2011. By Wanted. RS2 Build 681.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}

 

function InitiateSMART: Boolean;

begin

Result := False;

if (SMART_Server = 0) then

SMART_Server := 11;

if (not (SmartSetupEx(SMART_Server, True))) then

Exit;

SetTargetDC(SmartGetDC);

Result := WaitFunc(@RSReady, True, 100, 250, 90000, 120000);

end;

[/sCAR]

 

No that is not the issue, It wasnt that i couldnt use functions with SMART its that it wouldnt load. But I finally figured a solution to the problem.

 

What Your answer is referring to is Scars target application. The application im wokring on SMART is always the target. Thanks for the reply tho.

Link to comment
Share on other sites

Выбор трактора Шифенг: на что направить внимание

Тракторы марки Шифенг завоевали популярность на аграрном базаре из-за собственной надежности, многофункциональности и доступной цене. Но, чтобы выбрать подходящую модель, необходимо учесть несколько ключевых факторов. В данном посте будут рассмотрены, на что обратить внимание при выборе трактора Шифенг в зависимости от ваших потребностей и условий эксплуатации.

1. Определите цели использования

До этого всего, необходимо найти, для какой-никаких задач вы планируете использовать трактор. Основные направления применения тракторов Шифенг включают:

- Сельскохозяйственное производс: обработка почвы, посадка, сбор урожая, перевозка.
- Строительство:, подъем и транспортировка строительных материалов.
- Лесозаготовка: вывоз древесной породы, уборка на делянках.

Каждое направление может требовать различной мощности, производительности и дополнительных функций, по этой причине важно чётко понять свои цели.

2. Выбор мощности и типа двигателя

Тракторы Шифенг представлены в спектре мощностей, от легких моделей для маленьких хозяйств и заканчивая мощными машинами для крупных агроформирований. Главно учитывать следующие моменты:

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

3. Конструкция и качество

В момент выбора трактора главно обратить внимание на его конструкцию и качество материалов. Тракторы Шифенг довольно частенько делают из крепких сплавов, что наращивает их долговечность. Также проверьте:

- Тип трансмиссии: механическая либо гидростатическая, любая из которых имеет свои плюсы и минусы.
- Подвеска: наличие фронтальной и задней подвески подсобляет улучшить устойчивость и маневренность.

4. Комплектация и дополнительные опции

Дополнительные функции могут существенно воздействовать на комфорт и функциональность работы с трактором. При рассмотрении модели обратите внимание на:

- Наличие фар и освещения для работы в темное время суток.
- Кабина: превосходно утепленная и оснащенная системами вентиляции и кондиционирования значительно повысит комфорт оператора.
- Дополнительное оборудование: возможность установки различной подвесного либо прицепного оборудования (плуг, культиватор, фреза и так далее).

5. Сервис и гарантия

Важно учитывать доступность сервисного обслуживания и наличие запчастей. Выучите:

- Гарантийные условия: они могут варьироваться в зависимости от производителя.
- Квалификация сервисного центра: его возможности по ремонту и обслуживанию тракторов.

6. Бюджет

Помните о https://www.lettucegdb.com/community/home.php?mod=space&uid=8543 вашем бюджете. Тракторы Шифенг делают отличное предложение широкий ценовой диапазон, но также важно учесть расходы на эксплуатацию, обслуживание и возможные ремонты в будущем. Сравните разные модели и изберите ту, которая лучшим образом соответствует вашим финансовым способностям.

Заключение

Выбор трактора Шифенг это ответственный процесс, который зависит от большого колличества факторов. Определите цели его использования, учитывайте мощность и тип двигателя, качество конструкции, дополнительные функции, доступность сервиса и Свой бюджет. Правильно подобранный трактор станет надёжным помощником в вашем хозяйстве, обеспечивая эффективность и продуктивность работы на долгие годы. Не торопитесь с покупкой, лучше заранее соберите всю нужную информацию и проконсультируйтесь с специалистами, чтоб сделать обоснованный выбор.
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
  • Create New...