Register for your free account! | Forgot your password?

Go Back   elitepvpers > Popular Games > Silkroad Online > SRO Coding Corner
You last visited: Today at 03:45

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Guide] Using edxSilkroadProxy to Create a Simple AutoIt Clientless

Discussion on [Guide] Using edxSilkroadProxy to Create a Simple AutoIt Clientless within the SRO Coding Corner forum part of the Silkroad Online category.

Reply
 
Old   #1

 
elite*gold: 260
Join Date: Aug 2008
Posts: 560
Received Thanks: 3,779
[Guide] Using edxSilkroadProxy to Create a Simple AutoIt Clientless

Warning: Do not use on ISRO due to the 7 day ban on a wrong opcode.. Use this only for educational purposes and a reference!

Here it is! The third and final guide in my small series relating to the Silkroad proxy project. From here you will learn how to make a simple clientless that can spawn in game using the edxSilkroadProxy. Included is support for character listing and server stats. Be sure to read through the entire guide and code before trying to make your own version!

Using edxSilkroadProxy to Create a Simple AutoIt Clientless

I. Purpose

The purpose of this guide is to show how limitless development is with the right tools at our disposal. For this guide, we will be using the edxSilkroadProxy project as the main driving force behind a simple clientless built in AutoIt. The clientless will be able to request and display the server stats, process the character listing packet, and login to the world server. It might not seem like much, but remember we are using AutoIt to demonstrate how easy the task is due to how our proxy is setup.

You can use any language you wish though as long as it supports the Winsock API. This clientless will allow you to login, but that’s as far as it goes. If you want to make your own logger or power level tool or whatever, a lot more programming is needed. However, the basics of what you need to do are shown. Let’s get started!

II. Requirements

This guide uses the “A Simple Silkroad Proxy Reference” guide previously posted. You will need to have read that guide and downloaded the project files so you have the edxSilkroadProxy to run. While you do not have to fully understand how the proxy works, it helps a lot in being able to know what you have to code in the clientless.

As the title mention, this guide will use AutoIt, so you need to download the latest version and get it installed. Only the built in functions are used in my code so you will not have to download any extra modules. You can also port the code to another language if you wish. I just used AutoIt to really make a point about the importance of design and making life easier through creative means.

III. Theory

The edxSilkroadProxy is designed to allow us to make clientless programs easier. First, we do not have to worry about any packet encryption or security bytes. This immediately makes the task ten times easier since we can just work with raw packets and send them directly to the proxy. Likewise when we are processing packets, we just parse them all as unencrypted and that’s it.

At this point, we need to look at which packets we do have to handle with the proxy in order to make our clientless. The proxy handles the handshake packets, 0x5000, so our clientless can ignore those. The handshake response packets, 0x9000 and 0x2001, are also handled for us. When the clientless receives the 0x2001 from the server, it is our job to send the 0x6100 reply packet which includes some information about our Silkroad version.

Assuming we send the right version the server is expecting, we will eventually get the patch version information via 0x600D. We can ignore those in our clientless. The proxy will request the server stats for us, so we do not have to initially request the server stats ourselves. If we want updated server stats though, then we can send the 0x6101 packet to request the stats.

Last but not least, the proxy handles the ping packet, 0x2002 for us so we do not have to setup our own timer to send it when it’s necessary (every 5 seconds there is not another packet sent). As you can see, we don’t have that much work in front of us! All we have to do is send one packet to be able to get to the point of being able to login. Once we are ready to login, we just have to send the login packet, 0x6102, once. For ISRO the proxy will handle the autologin logic for us. For other Silkroads, you have to send the login packet yourself again as needed based on server traffic or some error code.

When you get the results of the login packet, 0xA102, you need to parse the data if it’s successful to get the destination IP/Port to connect to. The proxy will have sent you a localhost address to connect to and will handle the remote world server address itself. Note that all you have to do is connect to the new IP/Port, you don’t have to handle anything else because the proxy does it for you!

When the server sends the world server login confirmation packet, 0xA103, it is your job to then request the character listing using the current opcode. From here, you can parse the character listing to get the available characters to login. When you are ready to login, you send the packet for the character selection using the current opcode. You have to be sure to parse the response packet for the character listing as well to make sure there was not an error selecting the character (wrong name, being deleted, etc…).

Once we join the world server, we will receive a lot of packets. You will want to look into parsing them as you need them for your programs. The player listing packet is long and not easy to parse. For this guide, we will ignore all of these packets and simple wait for the character id packet which comes bundled with the game time information. When we receive that packet, we will send the spawn opcode to join the world server!

Congratulations! You now have a simple clientless that can login to the world server. It will just stand there and not do anything, but it will stay connected since the proxy handle the ping packet. From here, you would code in your own clientless logic by parsing packets and responding to commands.

Be sure to read this theory section over a few times so you can follow the AutoIt code. The AutoIt code shows almost the minimal amount of packets you need to handle to make your own clientless. Be sure to read the comments as well!

Just for some final notes, the proxy does not handle the image code, so you will not be able to use the clientless on those Silkroad versions which still have an image code unless you use my old Image Code work and integrate it into the proxy or your own clientless. For CSRO, which uses a driver in the client to prevent clientless, you won’t get too far on that version either since you would need to crack their security first. If anything though, you can at least make clientless Server Stats programs .

IV. Implementation

The complete code to the clientless is included. It will work fine for ISRO 1.205 but will need updating for future Silkroad versions where the opcodes change. The upcoming Legend4+ patch appears to change the opcodes so do not use this with old opcodes to avoid a ban.

If you start looking at the logic I used for packet building and parsing, it’s pretty neat. Rather than using traditional methods that complicate the code, I came up with this approach to easily work with the packet information. This code is mine and any resemble to other code on the net is purely coincidental. This code is released under the public domain and you can use it however you need to without any restrictions from me.
Code:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <string.au3>

Global $controlArray[37][5]

Global $globalParseIndex = 0
Global $globalParseSize = 0
Global $globalParseBuffer = ""

Global $globalSendBuffer = ""
Global $globalSendSize = 0

Global $mainwindow = 0

Global $serverStatsTimer = 0
Global $doRequestStats = false

;SplashImageOn("edxLabs Proudly Presents...", "beeker2.jpg", 304, 378)
;Sleep(3000)
;SplashOff()

TCPStartup()

$socket = TCPConnect("127.0.0.1", 16000)
If $socket = -1 Then
	MsgBox(64, "edxAutoitClientless", "Connection Failure.")
	Exit
EndIf

$mainwindow = GUICreate("edxAutoItClientless", 800, 600)
GUISwitch($mainwindow)
$tab = GUICtrlCreateTab(10, 10, 800 - 20, 600 - 20)

$tab0 = GUICtrlCreateTabItem("Home")


$tab1 = GUICtrlCreateTabItem("Server Stats")

For $i = 0 to 18
	$controlArray[$i][0] = GUICtrlCreateInput("000", 20, 40 + $i * 20, 25, 20)
	$controlArray[$i][1] = GUICtrlCreateInput("Servername", 50, 40 + $i * 20, 90, 20)
	$controlArray[$i][2] = GUICtrlCreateInput("0000", 140, 40 + $i * 20, 30, 20)
	$controlArray[$i][3] = GUICtrlCreateInput("0000", 170, 40 + $i * 20, 30, 20)
	$controlArray[$i][4] = GUICtrlCreateInput("00", 200, 40 + $i * 20, 20, 20)
Next
For $i = 19 to 36
	$controlArray[$i][0] = GUICtrlCreateInput("000", 20 + 240, 40 + ($i - 19) * 20, 25, 20)
	$controlArray[$i][1] = GUICtrlCreateInput("Servername", 50 + 240, 40 + ($i - 19) * 20, 90, 20)
	$controlArray[$i][2] = GUICtrlCreateInput("0000", 140 + 240, 40 + ($i - 19) * 20, 30, 20)
	$controlArray[$i][3] = GUICtrlCreateInput("0000", 170 + 240, 40 + ($i - 19) * 20, 30, 20)
	$controlArray[$i][4] = GUICtrlCreateInput("00", 200 + 240, 40 + ($i - 19) * 20, 20, 20)
Next

$tab2 = GUICtrlCreateTabItem("Login")
GUICtrlCreateLabel("Account: ", 20, 43, 50)
Global $controlName = GUICtrlCreateInput("", 80, 40, 121, 20, BitOR($SS_LEFT, $ES_PASSWORD))
GUICtrlCreateLabel("Password: ", 20, 63, 50)
Global $controlPass = GUICtrlCreateInput("", 80, 60, 121, 20,  BitOR($SS_LEFT, $ES_PASSWORD))
GUICtrlCreateLabel("Server: ", 20, 83, 50)
Global $controlServer = GUICtrlCreateCombo("xian", 80, 80, 121, 20)
GUICtrlSetData(-1, "aege|troy|athens|oasis|venice|greece|alps|olympus|tibet|babel|redsea|rome|sparta|********|pacific|alexander|persia|zeus|poseidon|hercules|odin|mercury|mars|saturn|venus|uranus|pluto|neptune|hera|gaia|eos|phoenix|ares|iris|titan|apollo") ; add other item snd set a new default
Global $controlLogin = GUICtrlCreateButton("Login!", 125, 105, 75)
Global $controlLog = GUICtrlCreateEdit("Welcome to edxAutoItClientless!" & @CRLF, 20, 150, 755, 420, $ES_AUTOVSCROLL + $WS_VSCROLL)
GUICtrlSetData($controlLog, "Made By: pushedx" & @CRLF, 1)
GUICtrlSetData($controlLog, "" & @CRLF, 1)
Global $controlCharacter = GUICtrlCreateCombo("Character Select", 300, 40, 121, 20)
Global $controlJoin = GUICtrlCreateButton("Let's Roll!", 430, 40, 75, 20)
GUISetState(@SW_SHOW)

$loginAttempts = 0

while 1
	UpdateGui()
	If @error Then
		ExitLoop
	Endif

	if $doRequestStats and TimerDiff($serverStatsTimer) > 3000 Then
		BeginPacket(0x6101)
		EndPacket()
		TCPSend($socket, GetPacket())
		$doRequestStats = False ; Wait for the new packet to be received
	Endif

	$packetSize = TryReadWord($socket)
	If @error == 0 Then
		$packetOpcode = ReadWord($socket)
		If @error Then
			ExitLoop
		Endif

		$packetSecurity = ReadWord($socket)
		If @error Then
			ExitLoop
		Endif

		$packetData = ReadArray($socket, Dec($packetSize))
		If @error Then
			ExitLoop
		Endif

		;MsgBox(0, "", "$packetSize =" & $packetSize & chr(13) & "$packetOpcode =" & HexToStrWord($packetOpcode)  & chr(13) & "$packetSecurity =" & $packetSecurity  & chr(13) & $packetData)

		Switch $packetOpcode
			case "2001" ; Identify
				BeginParse($packetData, Dec($packetSize))

				$field1 = Dec(ParseWord()) ; length
				$field2 = ParseAscii($field1)

				if $field2 == "GatewayServer" then
					BeginPacket(0x6100)
					AppendByte(18) ; ISRO locale
					AppendWord(9) ; length
					AppendString("SR_Client") ; identity
					AppendDword(205) ; version
					EndPacket()
					TCPSend($socket, GetPacket())
				elseif $field2 == "AgentServer" then
					; Nothing to do here
				endif

			case "A101" ; Server stats
				$doRequestStats = true
				BeginParse($packetData, Dec($packetSize))

				$field1 = Dec(ParseByte())
				$field2 = Dec(ParseByte())
				$coreNameLength = Dec(ParseWord())
				$coreName = ParseAscii($coreNameLength)
				$nullTerm = ParseByte() ; null terminator

				$nextServer = Dec(ParseByte())
				$index = 0
				while $nextServer == 1
					$serverId = Dec(ParseWord())
					$serverNameLength = Dec(ParseWord())
					$serverName = ParseAscii($serverNameLength)
					$serverCur = Dec(ParseWord())
					$serverMax = Dec(ParseWord())
					$serverState = Dec(ParseByte())
					$nextServer = Dec(ParseByte())

					GUICtrlSetData($controlArray[$index][0], $serverId)
					GUICtrlSetData($controlArray[$index][1], $serverName)
					GUICtrlSetData($controlArray[$index][2], $serverCur)
					GUICtrlSetData($controlArray[$index][3], $serverMax)
					GUICtrlSetData($controlArray[$index][4], $serverState)

					$index = $index + 1
				WEnd

				$serverStatsTimer = TimerInit()

			case "A102" ; Login result
				BeginParse($packetData, Dec($packetSize))
				$result = Dec(ParseByte())
				if $result == 1 Then
					$loginId = Dec(ParseDword())
					$ipNameLength = Dec(ParseWord())
					$ipName = ParseAscii($ipNameLength)
					$ipPort = Dec(ParseWord())
					AppendStatusText("You are ready to join the world server!")
					AppendStatusText("Connecting to " & $ipName & ":" & $ipPort)
					$socket = 0
					$socket = TCPConnect($ipName, $ipPort) ; All we have to do is connect to the new IP/Port
					$doRequestStats = False
				Else
					$result = Dec(ParseByte()) ; Some error, we need to handle them all in a real program
					if $result == 5 Then
						$loginAttempts = $loginAttempts + 1
						AppendStatusText("Could not connect due to server traffic [" & $loginAttempts & "]")
					Else
						AppendStatusText("There was an error logging into this account")
					EndIf
				EndIf

			case "A103" ; World server login result
				BeginParse($packetData, Dec($packetSize))
				$result = Dec(ParseByte())
				if $result == 1 Then
					AppendStatusText("You are now connected to the world server!")
					BeginPacket(0x749F) ; Request character listing [TODO: Update each opcode change]
					AppendByte(2) ; Request list
					EndPacket()
					TCPSend($socket, GetPacket())
				EndIf

			case "B49F" ; Char listing [TODO: Update each opcode change]
				BeginParse($packetData, Dec($packetSize))
				$operation = Dec(ParseByte())
				if $operation == 2 then ; char listing
					$result = Dec(ParseByte())
					$charCount = Dec(ParseByte())
					AppendStatusText("Found " & $charCount & " characters")
					For $c = 1 to $charCount
						$charType = Dec(ParseDword())
						$charNameLength = Dec(ParseWord())
						$charName = ParseAscii($charNameLength)
						AppendStatusText("Found character: " & $charName)

						GUICtrlSetData($controlCharacter, $charName, 1)

						$charVol = Dec(ParseByte())
						$charLvl = Dec(ParseByte())
						AppendStatusText("Level: " & $charLvl)
						$charExp = Dec(ParseQWord())
						$charStr = Dec(ParseWord())
						$charInt = Dec(ParseWord())
						$charAttr = Dec(ParseWord())
						$charHp = Dec(ParseDword())
						$charMp = Dec(ParseDword())
						AppendStatusText("HP/MP: " & $charHp & "/" & $charMp)
						$doDelete = Dec(ParseByte())
						if $doDelete == 1 then
							$charMinsToDel = Dec(ParseDword())
						EndIf
						$unk1 = Dec(ParseWord())
						$unk2 = Dec(ParseByte())

						$itemCount = Dec(ParseByte())
						AppendStatusText("This character has " & $itemCount & " items equipped.")
						For $i = 1 to $itemCount
							$itemId = Dec(ParseDword())
							$itemPlus = Dec(ParseByte())
							AppendStatusText("[" & $itemId & "][+ " & $itemPlus & "]")
						Next

						$itemCount = Dec(ParseByte())
						AppendStatusText("This character has " & $itemCount & " avatar items equipped.")
						For $i = 1 to $itemCount
							$itemId = Dec(ParseDword())
							$itemPlus = Dec(ParseByte())
							AppendStatusText("[" & $itemId & "][+ " & $itemPlus & "]")
						Next

						AppendStatusText("")
					Next
				Endif

			case "B7B0" ; Char selection (205) [TODO: Update each opcode change]
				BeginParse($packetData, Dec($packetSize))
				$result = Dec(ParseByte())
				if $result == 1 then
					AppendStatusText("Joining the game now...")
				else
					AppendStatusText("There was an error selecting this character. Please choose a different one.")
				EndIf

			case "332A" ; Char id and time (205) [TODO: Update each opcode change]
				BeginParse($packetData, Dec($packetSize))
				$charId = ParseDword()
				$time_celestialPosition = Dec(ParseWord()) ; moon/sun
				$time_hrs = Dec(ParseByte())
				$time_mins = Dec(ParseByte())

				AppendStatusText("My Character Id: " & $charId)
				AppendStatusText("Time " & $time_hrs & ":" & $time_mins)
				AppendStatusText("Celestial Position: " & $time_celestialPosition)

				BeginPacket(0x328A) ; Send spawn packet [TODO: Update each opcode change]
				EndPacket()
				TCPSend($socket, GetPacket())
		EndSwitch
	ElseIf @error <> -3 Then
		ExitLoop
	Endif
wend

TCPShutdown()

;----------------------------------------------------------------------------------------------------

Func ReadByte($socket)
	$lb = TCPRecv($socket, 1)
	while $lb == ""
		UpdateGui()
		If @error Then
			SetError(-2)
			return 0
		EndIf
		$lb = TCPRecv($socket, 1)
		If @error Then
			SetError(-1)
			return 0
		EndIf
	WEnd
	return Hex(Binary($lb))
EndFunc

;----------------------------------------------------------------------------------------------------

Func ReadWord($socket)
	$hb = TCPRecv($socket, 1)
	while $hb == ""
		UpdateGui()
		If @error Then
			SetError(-2)
			return 0
		EndIf
		$hb = TCPRecv($socket, 1)
		If @error Then
			SetError(-1)
			return 0
		EndIf
	WEnd
	$lb = TCPRecv($socket, 1)
	while $lb == ""
		UpdateGui()
		If @error Then
			SetError(-2)
			return 0
		EndIf
		$lb = TCPRecv($socket, 1)
		If @error Then
			SetError(-1)
			return 0
		EndIf
	WEnd
	return Hex(Binary($lb) & Binary($hb))
EndFunc

;----------------------------------------------------------------------------------------------------

Func TryReadWord($socket)
	$hb = TCPRecv($socket, 1)
	if $hb == "" Then
		SetError(-3)
		return 0
	EndIf
	$lb = TCPRecv($socket, 1)
	while $lb == ""
		UpdateGui()
		If @error Then
			SetError(-2)
			return 0
		EndIf
		$lb = TCPRecv($socket, 1)
		If @error Then
			SetError(-1)
			return 0
		EndIf
	WEnd
	SetError(0)
	return Hex(Binary($lb) & Binary($hb))
EndFunc

;----------------------------------------------------------------------------------------------------

Func ReadArray($socket, $count)
	$data = ""
	For $i = 1 to $count Step 1
		UpdateGui()
		If @error Then
			SetError(-2)
			return 0
		EndIf
		$data = $data & ReadByte($socket)
		If @error Then
			SetError(-1)
			return 0
		EndIf
	Next
	return $data
EndFunc

;----------------------------------------------------------------------------------------------------

Func HexToStrWord($var)
	$len = StringLen($var)
	if $len > 4 then
		return StringRight($var, 4)
	elseif $len == 4 then
		return $var
	elseif $len == 3 then
		return "0" & $var
	elseif $len == 2 then
		return "00" & $var
	elseif $len == 1 then
		return "000" & $var
	endif
EndFunc

;----------------------------------------------------------------------------------------------------

Func HexToStrDword($var)
	$len = StringLen($var)
	if $len > 8 then
		return StringRight($var, 8)
	elseif $len == 8 then
		return $var
	elseif $len == 7 then
		return "0" & $var
	elseif $len == 6 then
		return "00" & $var
	elseif $len == 5 then
		return "000" & $var
	elseif $len == 4 then
		return "0000" & $var
	elseif $len == 3 then
		return "00000" & $var
	elseif $len == 2 then
		return "000000" & $var
	elseif $len == 1 then
		return "0000000" & $var
	endif
EndFunc

;----------------------------------------------------------------------------------------------------

Func HexToStrByte($var)
	$len = StringLen($var)
	if $len > 2 then
		return StringRight($var, 2)
	elseif $len == 2 then
		return $var
	else ; Error condition
		return "00"
	endif
EndFunc

;----------------------------------------------------------------------------------------------------

Func BeginParse($buffer, $size)
	$globalParseIndex = 1
	$globalParseSize = $size
	$globalParseBuffer = $buffer
EndFunc

;----------------------------------------------------------------------------------------------------

Func ParseByte()
	$result = StringMid($globalParseBuffer, $globalParseIndex, 2)
	$globalParseIndex = $globalParseIndex + 2
	return $result
EndFunc

;----------------------------------------------------------------------------------------------------

Func ParseWord()
	$low = ParseByte()
	$hi = ParseByte()
	return $hi & $low
EndFunc

;----------------------------------------------------------------------------------------------------

Func ParseDword()
	$low = ParseWord()
	$hi = ParseWord()
	return $hi & $low
EndFunc

;----------------------------------------------------------------------------------------------------

Func ParseQWord()
	$low = ParseDword()
	$hi = ParseDword()
	return $hi & $low
EndFunc

;----------------------------------------------------------------------------------------------------

Func ParseAscii($length)
	$result = StringMid($globalParseBuffer, $globalParseIndex, $length * 2)
	$globalParseIndex = $globalParseIndex + ($length * 2)
	$len = StringLen($result)
	$strResult = ""
	For $i = 1 to $len Step 2
		$strResult = $strResult & Chr(Dec(StringMid($result, $i, 2)))
	Next
	return $strResult
EndFunc

;----------------------------------------------------------------------------------------------------

Func ParseUnicode($length)
	$result = StringMid($globalParseBuffer, $globalParseIndex, $length * 4)
	$globalParseIndex = $globalParseIndex + ($length * 4)
	$len = StringLen($result)
	$strResult = ""
	For $i = 1 to $len Step 4
		$strResult = $strResult & ChrW(Dec(StringMid($result, $i, 4)))
	Next
	return $strResult
EndFunc

;----------------------------------------------------------------------------------------------------

Func BeginPacket($opcode)
	$globalSendBuffer = ""
	$globalSendSize = 0
	$sOpcode = HexToStrWord(Hex($opcode))
	$globalSendBuffer = StringMid($sOpcode, 3, 2) & StringMid($sOpcode, 1, 2)
	$globalSendBuffer = $globalSendBuffer & "0000" ; Security bytes
	;MsgBox(0, "", $globalSendBuffer)
EndFunc

Func AppendByte($value)
	$sValue = HexToStrByte(Hex($value))
	$globalSendBuffer = $globalSendBuffer & $sValue
	$globalSendSize = $globalSendSize + 1
EndFunc

Func AppendWord($value)
	$sValue = HexToStrWord(Hex($value))
	$globalSendBuffer = $globalSendBuffer & StringMid($sValue, 3, 2) & StringMid($sValue, 1, 2)
	$globalSendSize = $globalSendSize + 2
EndFunc

Func AppendDword($value)
	$sValue = HexToStrDword(Hex($value))
	$globalSendBuffer = $globalSendBuffer & StringMid($sValue, 7, 2) & StringMid($sValue, 5, 2) & StringMid($sValue, 3, 2) & StringMid($sValue, 1, 2)
	$globalSendSize = $globalSendSize + 4
EndFunc

Func AppendString($value)
	For $i = 1 to StringLen($value) Step 1
		$xh = StringMid($value, $i, 1)
		$sValue = HexToStrByte(Hex(Asc($xh)))
		$globalSendBuffer = $globalSendBuffer & $sValue
		$globalSendSize = $globalSendSize + 1
	Next
EndFunc

Func EndPacket()
	$sSize = HexToStrWord(Hex($globalSendSize))
	$globalSendBuffer = (StringMid($sSize, 3, 2) & StringMid($sSize, 1, 2)) & $globalSendBuffer
	;MsgBox(0, "", $globalSendBuffer)
EndFunc

Func GetPacket()
	return _HexToString($globalSendBuffer)
EndFunc

;----------------------------------------------------------------------------------------------------

Func UpdateGui()
	$msg = GUIGetMsg()
	Select
    Case $msg = $GUI_EVENT_CLOSE
		SetError(-2)
		Return

	Case $msg = $controlJoin
		$n = GUICtrlRead($controlCharacter, 1)
		if StringLen($n) == 0 then
			$n = GUICtrlRead($controlCharacter)
			if StringLen($n) == 0 then
				MsgBox(0, "", "Please choose a Character")
				return
			endif
		endif

		if StringCompare($n, "Character Select") == 0 then
			MsgBox(0, "", "Please choose a Character")
			return
		endif

		BeginPacket(0x77B0) ; [TODO: Update each opcode change]
		AppendWord(StringLen($n))
		AppendString($n)
		EndPacket()
		TCPSend($socket, GetPacket())

		AppendStatusText("Attempting to login with character: " & $n)

	Case $msg = $controlLogin
		$n = GUICtrlRead($controlName)
		if StringLen($n) == 0 then
			MsgBox(0, "", "Please enter an Account")
			return
		endif
		$p = GUICtrlRead($controlPass)
		if StringLen($p) == 0 then
			MsgBox(0, "", "Please enter a Password")
			return
		endif
		$s = GUICtrlRead($controlServer)

		;MsgBox(0, "", $n & " " & $p & " " & $s)

		$doRequestStats = False

		BeginPacket(0x6102)
		AppendByte(18)
		AppendWord(StringLen($n))
		AppendString($n)
		AppendWord(StringLen($p))
		AppendString($p)
		AppendWord(ServerToId($s))
		EndPacket()
		TCPSend($socket, GetPacket())

	EndSelect
EndFunc

;----------------------------------------------------------------------------------------------------

Func ServerToId($server)
	if StringCompare($server, "xian") == 0 Then
		return 65
	Endif
	if StringCompare($server, "aege") == 0 Then
		return 74
	Endif
	if StringCompare($server, "troy") == 0 Then
		return 76
	Endif
	if StringCompare($server, "athens") == 0 Then
		return 94
	Endif
	if StringCompare($server, "oasis") == 0 Then
		return 96
	Endif
	if StringCompare($server, "venice") == 0 Then
		return 102
	Endif
	if StringCompare($server, "greece") == 0 Then
		return 107
	Endif
	if StringCompare($server, "alps") == 0 Then
		return 113
	Endif
	if StringCompare($server, "olympus") == 0 Then
		return 114
	Endif
	if StringCompare($server, "tibet") == 0 Then
		return 132
	Endif
	if StringCompare($server, "babel") == 0 Then
		return 134
	Endif
	if StringCompare($server, "redsea") == 0 Then
		return 150
	Endif
	if StringCompare($server, "rome") == 0 Then
		return 151
	Endif
	if StringCompare($server, "sparta") == 0 Then
		return 152
	Endif
	if StringCompare($server, "********") == 0 Then
		return 156
	Endif
	if StringCompare($server, "pacific") == 0 Then
		return 159
	Endif
	if StringCompare($server, "alexander") == 0 Then
		return 162
	Endif
	if StringCompare($server, "persia") == 0 Then
		return 165
	Endif
	if StringCompare($server, "zeus") == 0 Then
		return 166
	Endif
	if StringCompare($server, "poseidon") == 0 Then
		return 174
	Endif
	if StringCompare($server, "hercules") == 0 Then
		return 178
	Endif
	if StringCompare($server, "odin") == 0 Then
		return 179
	Endif
	if StringCompare($server, "mercury") == 0 Then
		return 180
	Endif
	if StringCompare($server, "mars") == 0 Then
		return 181
	Endif
	if StringCompare($server, "saturn") == 0 Then
		return 182
	Endif
	if StringCompare($server, "venus") == 0 Then
		return 183
	Endif
	if StringCompare($server, "uranus") == 0 Then
		return 187
	Endif
	if StringCompare($server, "pluto") == 0 Then
		return 188
	Endif
	if StringCompare($server, "neptune") == 0 Then
		return 190
	Endif
	if StringCompare($server, "hera") == 0 Then
		return 191
	Endif
	if StringCompare($server, "gaia") == 0 Then
		return 194
	Endif
	if StringCompare($server, "eos") == 0 Then
		return 204
	Endif
	if StringCompare($server, "phoenix") == 0 Then
		return 205
	Endif
	if StringCompare($server, "ares") == 0 Then
		return 206
	Endif
	if StringCompare($server, "iris") == 0 Then
		return 207
	Endif
	if StringCompare($server, "titan") == 0 Then
		return 208
	Endif
	if StringCompare($server, "apollo") == 0 Then
		return 209
	Endif
EndFunc

;----------------------------------------------------------------------------------------------------

; Wrapper function to make life a little easier
Func AppendStatusText($text)
	GUICtrlSetData($controlLog, $text & @CRLF, 1)
EndFunc

;----------------------------------------------------------------------------------------------------
Here are some screenshots of the project in action!




V. Conclusion

Hopefully by now, you can understand how important design is. By designing our proxy in such a way that it handles the “tough” stuff for Silkroad, we can make programs in any language we want that are not limited by our ability to implement the Silkroad security in those languages. Furthermore, with a little creativity, you can see how easy it is to use AutoIt for a packet based program that looks pretty much like a C++ program would. There are some serious limitations to the language, but what you can really do with it just lies in your ability to program with it.

Study the code and the theory so you can take the concepts shown here and apply them into your own language. I’ve made a simple clientless in C#, C++, and AutoIt now using this approach and a friend has made them in VB.net and Java. Anything is doable, you just have to take the time and do it!

That wraps up this guide and the mini series. The first guide in the series showed us a simple proxy we can use for Silkroad. The second guide showed how to setup our own hook to use the client with the proxy. This third and final guide shows us how we can use a clientless with the proxy. There is still a lot of work that needs to be done though, so don’t stop here!

Drew “pushedx” Benton
edxLabs
pushedx is offline  
Thanks
45 Users
Old 08/21/2009, 10:12   #2
 
InvincibleNoOB's Avatar
 
elite*gold: 20
Join Date: Mar 2007
Posts: 4,277
Received Thanks: 2,990
#Approved.
InvincibleNoOB is offline  
Thanks
1 User
Old 08/21/2009, 10:32   #3
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
Freaking awesome o.O
soadmania is offline  
Old 08/21/2009, 14:23   #4
 
theoneofgod's Avatar
 
elite*gold: 20
Join Date: Mar 2008
Posts: 3,940
Received Thanks: 2,211
Wow, you never cease to amaze me with your guides! Good job!
theoneofgod is offline  
Old 08/21/2009, 14:58   #5
 
elite*gold: 0
Join Date: Jun 2008
Posts: 188
Received Thanks: 106
Haha, very nice. I also made my own server in AutoIt. Can move around and nothing more though. I honestly wouldn't recommend AutoIt for anything serious
maxbot is offline  
Old 08/21/2009, 15:21   #6



 
lolrko's Avatar
 
elite*gold: 280
The Black Market: 119/0/0
Join Date: Oct 2007
Posts: 3,578
Received Thanks: 2,276
woooow i am so amazed , it's like the only thing i was searching for !!
thank you very much
lolrko is offline  
Old 08/21/2009, 17:14   #7
 
x_king_x's Avatar
 
elite*gold: 20
Join Date: Nov 2008
Posts: 746
Received Thanks: 147
Freaky Awesome Work drew
keep it up
x_king_x is offline  
Old 08/25/2009, 22:56   #8
 
Shadowz75's Avatar
 
elite*gold: 0
Join Date: Mar 2009
Posts: 443
Received Thanks: 597
little tsro update:
line 115
Quote:
if $field2 == "GatewayServer" then
BeginPacket(0x6100)
AppendByte(18) ; ISRO locale
AppendWord(9) ; length
AppendString("SR_Client") ; identity
AppendDword(205) ; version
EndPacket()
change the
Quote:
AppendByte(18) ; ISRO locale
to
Quote:
AppendByte(12) ; TSRO locale
and change the version to
Quote:
AppendDword(206) ; version
line 193
Quote:
case "B49F" ; Char listing
change the "B49F" to "B007"

line 187
Quote:
BeginPacket(0x749F) ; Request character listing
change the 0x749F to 0x7007
regards

line 245
Quote:
case "B7B0" ; Char selection
change the "B7B0" to "B001"

line 265
Quote:
BeginPacket(0x328A) ; Send spawn packet [TODO: Update each opcode change]
change the 0x328A to 0x3012

line 254
Quote:
case "332A" ; Char id and time
change the "332A"" to "3020"

line 564
Quote:
BeginPacket(0x77B0) ; [TODO: Update each opcode change]
change the 0x77B0 to 0x7001

line 589
Quote:
AppendByte(18)
change the 18 -> 12

change the function "ServerToId" to this:
Quote:
Func ServerToId($server)
if StringCompare($server, "´M¯³") == 0 Then
return 202
Endif
if StringCompare($server, "¤k´E") == 0 Then
return 198
Endif
if StringCompare($server, "¥ñ¿ª") == 0 Then
return 197
Endif
if StringCompare($server, "»Èªe") == 0 Then
return 196
Endif
if StringCompare($server, "¬PªÅ") == 0 Then
return 195
Endif

EndFunc
line 65
change the line
Quote:
GUICtrlSetData(-1, "aege|troy|athens|oasis|venice|greece|alps|olympus |tibet|babel|redsea|rome|sparta|********|pacific|a lexander|persia|zeus|poseidon|hercules|odin|mercur y|mars|saturn|venus|uranus|pluto|neptune|hera|gaia |eos|phoenix|ares|iris|titan|apollo") ; add other item snd set a new default
to
Quote:
GUICtrlSetData(-1, "´M¯³|¤k´E|¥ñ¿ª|¬PªÅ|»Èªe") ; add other item snd set a new default
the imagecode opcodes are:
Quote:
public const string ImageCode = "2322";
public const string ImageCodeData = "6323";
public const string ImageCodeResult = "A323";
i dunno how to compress it in autoit , im using c# anyway, but i wanted to share the tsro opcodes.
Shadowz75 is offline  
Thanks
3 Users
Old 08/29/2009, 17:35   #9
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
can i join to edxLabs guild

my IGN is Aspirine
soadmania is offline  
Old 09/04/2009, 23:24   #10
 
elite*gold: 0
Join Date: Aug 2008
Posts: 460
Received Thanks: 48
Can anyone change packets to work it at sjsro?
Spox One is offline  
Old 09/21/2009, 08:12   #11
 
hadyz3's Avatar
 
elite*gold: 0
Join Date: Apr 2009
Posts: 420
Received Thanks: 52
will this work in KSRO???
hadyz3 is offline  
Old 09/21/2009, 22:09   #12
 
Shadowz75's Avatar
 
elite*gold: 0
Join Date: Mar 2009
Posts: 443
Received Thanks: 597
whats the vsro locale and the current version?i dont have the client
regards
Shadowz75 is offline  
Old 09/22/2009, 03:42   #13
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
Quote:
Originally Posted by Shadowz75 View Post
whats the vsro locale and the current version?i dont have the client
regards
check out the edxSilkroadLoader. u can find the local there.
soadmania is offline  
Thanks
1 User
Old 09/22/2009, 06:32   #14
 
Kazuya¹'s Avatar
 
elite*gold: 0
Join Date: Apr 2007
Posts: 449
Received Thanks: 236
Quote:
Originally Posted by Shadowz75 View Post
whats the vsro locale and the current version?i dont have the client
regards
1.052
Kazuya¹ is offline  
Thanks
1 User
Old 09/22/2009, 18:01   #15
 
elite*gold: 0
Join Date: Nov 2005
Posts: 26
Received Thanks: 1
Dear Mr Pushedx
I try to use your edxsilkroadproxy lite to login by autoit but my clientless disconnect immediately when I try to use some HP, MP, Pick Item, It disconnect because Opcode Inventory Update, I wonder if there is any problem with your edxsilkroadproxy lite ? And could you fix it ?

Thanks so much !
zeldalcl is offline  
Reply


Similar Threads Similar Threads
C# Clientless using edxSilkroadProxy
05/23/2011 - SRO Hacks, Bots, Cheats & Exploits - 21 Replies
Here is a basic clientless written in C# using drew bentons edxSilkroadProxy. The code isn't complicated at all, using the basics which the .net framework provides. It doesn't provide any cool features, that's up to you to add. ;) Source Download ( No binaries ): http://torquesro.info/download/tClientless%20C%23. rar There will be more releases @ www.torquesro.info/forum for different sro versions, and different programming languages. ;)
[GUIDE] How to create Scripts/bots with AutoIT
09/22/2010 - Tutorials - 6 Replies
for all who want to learn something or create bots for browsergames, mmorpgs and other games download Autoit here: http://www.autoitscript.com/cgi-bin/getfile.pl?au toit3/autoit-v3-setup.exe Now run the Scite Script Editor this is where you type in your code, let check your code if errors are in it and compile it to executable exe file. the first thing you need are the coordinates of your mouse to find locations on the screen, like skill buttons, status bars, or just positions which...
Is it possible to create a simple silkroad bot using java?
03/26/2009 - Silkroad Online - 2 Replies
anyone ?
(GUIDE)How to create own scripts/bots with AutoIt
11/19/2008 - Rappelz - 4 Replies
for all who want to learn something or create bots for browsergames, mmorpgs and other games download Autoit here: http://www.autoitscript.com/cgi-bin/getfile.pl?au toit3/autoit-v3-setup.exe Now run the Scite Script Editor this is where you type in your code, let check your code if errors are in it and compile it to executable exe file. the first thing you need are the coordinates of your mouse to find locations on the screen, like skill buttons, status bars, or just positions which...
Ghostmouse - Create your own simple macros!
05/11/2006 - Conquer Online 2 - 8 Replies
Hi Everyone, I recently Stumbled accross this little program, (Dont know if its been posted before) It is used for recording and playing back mouse scripts. They can also be saved and sent to others using the same program. It is really useful to make a simple macro like a meditation leveler etc. Here it is. Feel free to scan. (A Good online scanner is http://virusscan.jotti.org) Edit: P.S Sorry for posting in the wrong forum. Can a mod please move this?



All times are GMT +1. The time now is 03:45.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.