Jump to content
Eternal Lands Official Forums
marco.link

Trying to create a bot

Recommended Posts

Hail everyone!

 

I am trying to create a bot in PHP.

 

I successfully connected to the testserver (eternal-lands.network-studio.com:2001) and send a login-request.

The server answered with "Testserver." and a ping-request, which I answer with the same package as received (as done in the sourcecode of the el-client).

 

But I get no access to my account.

 

Is there a step I forgot?

 

Here is the class I wrote for the client:

<?php
require_once("ELConstants.inc.php");

class ELClient {
 var $host;
 var $port;
 var $socket;
 var $username;
 var $password;
 var $logger;

 // Flags
 var $loggedIn;
 var $gotOpeningScreen;

 function ELClient($host, $port) {
$this->host = $host;
$this->port = $port;
$this->logger = NULL;
$this->socket = FALSE;

$this->loggedIn = FALSE;
$this->gotOpeningScreen = FALSE;
 }

 function setLogger(&$logger) {
$this->logger = $logger;
 }

 function connect() {
$result = FALSE;

$this->logInfo("Connecting to '%s:%s' ...", $this->host, $this->port);
$this->socket = fsockopen($this->host, $this->port);
socket_set_blocking($this->socket, TRUE);

if ($this->socket !== FALSE) {
  $this->logInfo("Connection established.");
  $this->awaitOpeningScreen();
  $result = TRUE;
} else {
  $this->logInfo("ERROR: Connection Failed!");
}

return $result;
 }

 function login($username, $password, $timeout = 1) {
global $SERVER_COMMANDS, $CLIENT_COMMANDS;
$this->username = $username;
$this->password = $password;
$this->logInfo("Logging in as '%s' ...", $username);
$this->send($SERVER_COMMANDS["LOG_IN"], sprintf("%s %s", $username, $password));

$loops = 0;
while (!$this->loggedIn && ($loops < $timeout)) {
  $packet = $this->receive();

  if (strlen($packet) > 0) {
	$this->processPacket($packet);
  }

  $loops++;
  sleep(1);
}

if (!$this->loggedIn) {
  $this->logInfo("ERROR: Failed to login!");
}

return $this->loggedIn;
 }

 function awaitOpeningScreen($timeout = 1) {
global $SERVER_COMMANDS;

$this->send($SERVER_COMMANDS["SEND_OPENING_SCREEN"]);

$loops = 0;	
while (!$this->gotOpeningScreen && ($loops < $timeout)) {
  $packet = $this->receive();

  if (strlen($packet) > 0) {
	$this->processPacket($packet);
  }

  $loops++;
  sleep(1);
}
 }

 function getPacketType($packet) {
return ord(substr($packet, 0, 1));
 }

 function processPacket($packet) {
global $CLIENT_COMMANDS, $SERVER_COMMANDS;
$packetType = $this->getPacketType($packet);

switch ($packetType) {
  case $CLIENT_COMMANDS["LOG_IN_OK"]:
	  $this->logInfo("Login successful!");
	  $this->loggedIn = TRUE;
	break;
  case $CLIENT_COMMANDS["LOG_IN_NOT_OK"]:
	  $this->logInfo("ERROR: Invalid password!");
	  $this->loggedIn = FALSE;
	break;
  case $CLIENT_COMMANDS["RAW_TEXT"]:
	  $this->processRawText(substr($packet, 1));
	break;
  case $CLIENT_COMMANDS["PING_REQUEST"]:
	  $this->logInfo("Got ping-request. Answering.");
	  $this->send($packetType, substr($packet, 1));
	break;
  case $CLIENT_COMMANDS["YOU_DONT_EXIST"]:
	  $this->logInfo("ERROR: Invalid username!");		
	break;
  default:
	$this->logInfo("Received an unkown packet (Type=%s):\n%s",
	  $packetType, substr($packet, 1));		
}
 }

 function isColor($value) {
global $COLORS;

return (($value >= $COLORS["LBOUND"]) && ($value <= $COLORS["UBOUND"]));
 }

 function processRawText($packet) {
global $COLORS;
$channel = substr($packet, 1, 1);
$text = substr($packet, 2);

if ($this->isColor(ord(substr($packet, 2, 1)))) {
  $color = substr($packet, 2, 1);

  $text = substr($packet, 4);
}

$this->gotOpeningMessage = (($color == $COLORS["GREEN1"])
  && (is_string(stristr($packet, "Test"))));

$this->logInfo("Received a chat-message on channel %s:\n%s", 
  ord($channel), $text);
 }

 function logInfo(/* string */ $format /* [, mixed args] */) {
if ($this->logger !== NULL) {
  $args = func_get_args();
  $write_arg = call_user_func_array("sprintf", $args);

  echo $write_arg . "\n";
  $this->logger->write($write_arg);
  flush();
}
 }

 function logout() {
global $SERVER_COMMANDS;
$this->username = "";
$this->password = "";
$this->loggedIn = FALSE;
$this->send($SERVER_COMMANDS["BYE"]);
 }

 function disconnect() {
fclose($this->socket);
 }

 function receive() {
$packet = fread($this->socket, 1024);

return $packet;
 }

 function send($commandType, $data = "") {
return fwrite($this->socket, chr($commandType) . $data);
 }
}
?>

 

Thank you for your reply!

 

Kind regards!

Edited by Elfasar

Share this post


Link to post
Share on other sites

What do you mean you get no access to your account?

 

Also, why are you using blocking mode?

 

Ah, yes.

I get no login.

I get no login confirmation from the server. It doesnt send it to the client.

 

I am using blocking-mode to avoid using a loop for reading from the socket.

PHP-documentation says, that fread() waits for completed transaction when reading from a blocked socket.

See this for further information to blocking a socket.

This is just a call to force blocking-mode on execution, but it is enabled by default.

Share this post


Link to post
Share on other sites

Just as a sidenote, php should be ok if you are running it as a standalone script, but if your intention is to build a web based bot script, the page will time out.

 

Nope.

You can set set_time_limit(0) to avoid timeout.

But its not my intention to use it as a webbased-script.

It use it as a commandline-script (# php startup.php).

That works.

 

Only administration should be done by website.

Share this post


Link to post
Share on other sites

Changed the code a little bit (edited the top message):

 

Inserted a function to await the opening screen, before login request.

So the "Testserver"-message will be received before I try to login.

The ping-request will be received after trying to login.

 

Logging in does still not work.

 

Here is the output of the script:

# php startup.php

Content-type: text/html

 

Starting up the Eternal Lands Bot 'Amilia'.

Connecting to 'eternal-lands.network-studio.com:2001' ...

Connection established.

Received a chat-message on channel 0:

Test server.

Logging in as 'Amilia' ...

Got ping-request. Answering.

ERROR: Failed to login!

Share this post


Link to post
Share on other sites

$this->send($SERVER_COMMANDS["LOG_IN"], sprintf("%s %s", $username, $password));

 function send($commandType, $data = "") {
return fwrite($this->socket, chr($commandType) . $data);
 }

these two lines stick out... I'm not that familiar with PHP, do you need to force the null at the end of a string when sending it? (the server is very picky) a missing null at the end of a line will likely cause problems

also, have another look at my_tcp_send() in multiplayer.c ... in particular, the packet's data length short-int immediately following the protocol (and while you're at it, reading the networking code for packet sending and receiving until your eyes hurt will probably give you a strong enough understanding to work quickly though client-server interaction)

Share this post


Link to post
Share on other sites

$this->send($SERVER_COMMANDS["LOG_IN"], sprintf("%s %s", $username, $password));

 function send($commandType, $data = "") {
return fwrite($this->socket, chr($commandType) . $data);
 }

these two lines stick out... I'm not that familiar with PHP, do you need to force the null at the end of a string when sending it? (the server is very picky) a missing null at the end of a line will likely cause problems

also, have another look at my_tcp_send() in multiplayer.c ... in particular, the packet's data length short-int immediately following the protocol (and while you're at it, reading the networking code for packet sending and receiving until your eyes hurt will probably give you a strong enough understanding to work quickly though client-server interaction)

 

The is no zero-terminated string in PHP like in C/C++.

I use the multiplayer.c as reference.

But i will take a look at the my_tcp_send()-routine again, 'cause of the packet -length-info.

Share this post


Link to post
Share on other sites

Solved the problem.

 

Separated the socket functions to a class and

worked some things out:

- First I send a heartbeat after connecting

- Then I send the login-data

- After that i wait for responce and check it for success

- If all works, I go into loop

 

Things I have missed:

- The login-data needs to be zero-terminated (others not, I found out with ethereal)

- Each packet has to be build a follows:

1 Byte: Packettype
2 Bytes: Length of the data + 1 (for packettype)
n Bytes: the data itself

 

ok. thats it. now it works as it should.

Edited by Elfasar

Share this post


Link to post
Share on other sites
- The login-data needs to be zero-terminated (others not, I found out with ethereal)

- Each packet has to be build a follows:

1 Byte: Packettype
2 Bytes: Length of the data + 1 (for packettype)
n Bytes: the data itself

thought so :) happy botting!

Share this post


Link to post
Share on other sites
- The login-data needs to be zero-terminated (others not, I found out with ethereal)

- Each packet has to be build a follows:

1 Byte: Packettype
2 Bytes: Length of the data + 1 (for packettype)
n Bytes: the data itself

thought so :P happy botting!

 

Nah, doesnt work right at the moment.

My bots gets eaten by a Grue.

Have to fix this somehow.

I think it runs into a timing-problem.

 

But the rest should work properly.

Share this post


Link to post
Share on other sites
Nah, doesnt work right at the moment.

My bots gets eaten by a Grue.

Have to fix this somehow.

I think it runs into a timing-problem.

My bots send the heartbeat every 15 seconds (I think default was 25).

Share this post


Link to post
Share on other sites
Nah, doesnt work right at the moment.

My bots gets eaten by a Grue.

Have to fix this somehow.

I think it runs into a timing-problem.

My bots send the heartbeat every 15 seconds (I think default was 25).

 

Jepp. That is correct.

 

But my bot isnt sending it again (just for the first time), because it stucks somehow.

I think that there is a problem with my loop.

It seems that it doesnt give time to the heartbeat-function to send or the socket doesnt do it.

 

I will try some other functions for working with sockets (PHP is very restricted in that).

Share this post


Link to post
Share on other sites

Ok. I got it to work correctly.

 

If someone needs to know something (e.g. how have I ...), post it here and I answer asap.

BUT: I will not answer anything on programming it self. I will not give a crash-course in programming.

 

Next time, I will create a small howto on getting a simple bot to work and post it here.

Share this post


Link to post
Share on other sites
Guest leader_of_clan_NET

ok, where can i find the ELConstants file?

 

also, what does the bot DO...it looks like it just stands there....?

 

thx

Edited by leader_of_clan_NET

Share this post


Link to post
Share on other sites

ok, where can i find the ELConstants file?

 

also, what does the bot DO...it looks like it just stands there....?

 

thx

Oh, hi.

 

You wanna use my bot?

 

It has grown up a little, got more features and is build very modular.

 

If you want it, you should send me an email and I will send you a simple bot I wrote in PHP (to use with PHP-CLI).

It can receive commands per PM and send PMs itself.

So you could work on it (not just from scratch) and modify it to your needs.

 

BUT: I will not give any support on it !!! Never !!!

So, if you really want to use it, you have to work on it for yourself!

 

And as I am very busy at the moment, I will not give you any informations on how to modify it!

And the more important: I will not modify it for you. You have to manage it yourself!

 

Greetings.

 

EDIT: I forgot to remind, that you should not expect some comments in that code!

Edited by Elfasar

Share this post


Link to post
Share on other sites
Guest leader_of_clan_NET

ok, where can i find the ELConstants file?

 

also, what does the bot DO...it looks like it just stands there....?

 

thx

Oh, hi.

 

You wanna use my bot?

 

It has grown up a little, got more features and is build very modular.

 

If you want it, you should send me an email and I will send you a simple bot I wrote in PHP (to use with PHP-CLI).

It can receive commands per PM and send PMs itself.

So you could work on it (not just from scratch) and modify it to your needs.

 

BUT: I will not give any support on it !!! Never !!!

So, if you really want to use it, you have to work on it for yourself!

 

And as I am very busy at the moment, I will not give you any informations on how to modify it!

And the more important: I will not modify it for you. You have to manage it yourself!

 

Greetings.

 

EDIT: I forgot to remind, that you should not expect some comments in that code!

 

 

please! we can edit it were programmers!

jsut wheres the file?

 

PLEASE!

Share this post


Link to post
Share on other sites

please! we can edit it were programmers!

jsut wheres the file?

 

PLEASE!

 

Oops.

That was quick reply ;)

 

Ok. I will attach them here later (if I'm allowed!?).

Share this post


Link to post
Share on other sites
Guest leader_of_clan_NET

please! we can edit it were programmers!

jsut wheres the file?

 

PLEASE!

 

Oops.

That was quick reply ;)

 

Ok. I will attach them here later (if I'm allowed!?).

 

 

dear kind sir, can you please jsut psot code here?

 

and use a normal e-mail thingy to send it, if u wanna attach...

Share this post


Link to post
Share on other sites

Please, I really need the file. could you PM me (on the forum, not game) the source? I REALLY REALLY NEED IT!!!

 

 

btw, I'm working with Leader of clan NET

Share this post


Link to post
Share on other sites

Please, I really need the file. could you PM me (on the forum, not game) the source? I REALLY REALLY NEED IT!!!

 

 

btw, I'm working with Leader of clan NET

 

Oh, sorry.

 

I have send an email to the Leader, but forgot to attach the sourcecode.

I have send it to you and the Leader now.

Fave fun with it.

 

Here is the link to the sourcecode!

 

But read the disclaimer given!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×