Jump to content
Eternal Lands Official Forums
kzar

Basic (noob) Question

Recommended Posts

Ok im trying to start my bot off as im getting a bit bored of doing the examples in my c book. Im using c and SDL_NET.

 

Anyway my question is this, how do i login? I thought this would be a good start as hopefully i should be able to see the bot appear if i put my character neer by where the bot logged off.

 

From reading the code I think its somthing like this..

 

send "140 username"

send "140 password"

 

or have i got the wrong end of the stick?

 

Cheers anyway, kzar

Share this post


Link to post
Share on other sites
snprintf (str, maxlen, "%c%s %s", LOG_IN, username, password);

send (str);

so "send 140 username password"

 

edit: i should say i was asking about the protocol not the code to do it, probably was unclearly written, sorry

Edited by kzar

Share this post


Link to post
Share on other sites

Ok well is that all you would have to do to make the character appear? I have written the program to do that and im pretty sure its sending it ok, but the bot isnt appearing at all.

 

oh wait i think its

"send 140user pass"

and i think its the character 140 represents not the number 140. thing is i thought it only went up to 127 or somthing :D

Edited by kzar

Share this post


Link to post
Share on other sites

You might find it easier to get someone's existing bot code and re-engineer it for your own purposes. That what I did: just strip out all the other crap and start from the bottom up with only the server interaction functions.

 

I'm away from my home system now, but maybe I'll post some basic bot code later. Or someone else can beat me to it today...

Share this post


Link to post
Share on other sites
Ok well is that all you would have to do to make the character appear? I have written the program to do that and im pretty sure its sending it ok, but the bot isnt appearing at all.

 

oh wait i think its

"send 140user pass"

and i think its the character 140 represents not the number 140. thing is i thought it only went up to 127 or somthing  ;)

Protocol information (courtesy of wytter):

 

The first byte specifies the action (client_serv.h). The next 2 bytes specify the length (unsigned short, little endian). The next part is the content of the package.

 

:)

 

 

[EDIT]

Its 256, not 127 (byte range, 2^8).

[/EDIT]

Edited by Placid

Share this post


Link to post
Share on other sites
i ment the ansi characters only went up to 127

Yes, the ANSI character go up to 127. Ent uses non-ANSI characters to specify the protocol. And you're right, the first byte should be 140, and there should be no space between it and the username.

Share this post


Link to post
Share on other sites

Heres the sniplet of relevant stuff.. did i get the wrong end of the stick of somthing?

 

char *hostname = "eternal-lands.solexine.fr";

int port = 2000;

IPaddress ipaddress;

TCPsocket tcpsock;

char *Username = "robocop";

char *Password = "blah";

int len, result;

char temp[200];

 

/* Send login packet */

temp[0] = 140; /* Put login character */

temp[1] = 200; /* Just shove anything in there temporarily */

strcat(temp, Username);

strcat(temp, " ");

strcat(temp, Password);

temp[1] = sizeof(temp);

printf("##Sending: %s\n", temp);

len = strlen(temp) + 1;

result = SDLNet_TCP_Send(tcpsock, temp, len);

Share this post


Link to post
Share on other sites

The message size is a short int, consisting of two bytes, not one. Also note that you specify a larger size (sizeof(tmp) == 200) then what you actually send (strlen(tmp)+1).

Share this post


Link to post
Share on other sites

ok. See thing it still seems to be sending the length in one character?

 

short int len;

int result;

char temp[200];

 

/* Send login packet */

temp[0] = 140; /* Put login character */

strcat(temp + 1, " "); /* Just shove anything in there temporarily */

strcat(temp, Username);

strcat(temp, " ");

strcat(temp, Password);

len = strlen(temp) + 1;

temp[1] = len;

printf("##Sending: %s\n", temp);

result = SDLNet_TCP_Send(tcpsock, temp, len);

 

edit: there are two spaces on the strcat(temp + 1, " ") but it seems to have got rid of them when i posted.

Edited by kzar

Share this post


Link to post
Share on other sites

strcat(temp + 1, " "); /* Just shove anything in there temporarily *

Unsafe. You don't know what's in the second byte and thereafter. If it's not zero, it's most likely to crash.

 temp[1] = len;

this first converts len to a single byte, and the assigns it to the second byte in the message.

 

How about this:

#define LOG_IN 140

unsigned short int len = strlen(username) + strlen(password)  + 4;

if (textlen > 200-4) {
 fprintf (stderr, "Meep! Message too long for buffer;
 exit (1);
}

msg[0] = LOG_IN;
*((unsigned short int*)(msg+1)) = textlen+3;
sprintf (msg+3, "%s %s", username, password);
result = SDLNet_TCP_Send(tcpsock, msg, len);

 

EDIT: edited three times in total. You may look now...

Edited by Grum

Share this post


Link to post
Share on other sites

i am shoving this all in main just to get it working originaly but its getting so confusing im gona try making a send packet function, cheers for the code, back in 10 mins (touch wood)

Share this post


Link to post
Share on other sites

Still doesnt work but im sure its almost there. Its so much simpler as a seperate function though, at least it makes sence now.

 

/* Send login packet */
sprintf (temp, "%s %s", Username, Password);
sendpacket(140, temp);

 

int sendpacket(int code, char *message)
{
   char temp[200];
   unsigned int packetlength;
   int len, result;
   
   /* Make sure its not going to overflow */
   if (strlen(message) - 4 > sizeof(temp))
   {
       printf("Message too long!");
       exit(2);
   }
   
   /* Figure out the length the packet would be */
   packetlength = strlen(message) + 4;
   len = strlen(message) + 4;
   
   /* Put packet together */
   temp[0] = code;    /* Put protocol code in */
   *((unsigned short int*)(temp +1 )) = packetlength + 3; /* Grum wrote this */
   strcat(temp, message); /* Add the message */
   
   /* Send the packet */
   printf("##Sending...\n");
   result = SDLNet_TCP_Send(tcpsock, temp, len);    
   if(result < len) 
   {
       printf("Didnt manage to send message");
       return -1;
   }
   else
   {
       printf("##Sent: '%s'\n", temp);
       return 0;
   }    
} 

Share this post


Link to post
Share on other sites

Good idea to split it off.

Now, then:

if (strlen(message) - 4 > sizeof(temp))

should be '+', not '-'.

strcat(temp, message); /* Add the message */

I think this is where it fails. The most significant byte of the message length is zero. strcat will interpret this as the end of string of the previous string, and start writing there. So better change that to something like

strcpy(temp+3,message);

 

Also, think about whether the length of the message you send is strlen(message)+3 or strlen(message)+4. I'm too tired.

 

PS: using strcat is DANGEROUS if you're not sure that string you are appending to is not NULL-terminated.

Edited by Grum

Share this post


Link to post
Share on other sites

for packet length its +4 because its

1 for the 140

2 for the len

and the last character is the null thing \0.

 

I think its working now, im seing a green haze appear for a second when i run the program!

 

Thanks for all that help, i learnt alot actualy :D .

Share this post


Link to post
Share on other sites

update: Got it to connect, hang around for 5 seconds, say hello wold, wait 5 seconds and disconect!

 

My next problem is with recieving data. ;)

All i seem to be getting is this "18546360". when i was expecting to get an you logged in ok packet. which is 250.

 

Im thinking maybe im doing the bytes wrong like before where im using one byte not two or somthing. :blink: . anyway here is my function to get incoming stuff. Its quite basic at the moment.

 

 

int incoming_thread(void *unused)
{
   char buffer[200];

   while (thread_die != -1) 
   {
       /* Incoming connection stuff */
       SDLNet_TCP_Recv(tcpsock, &buffer, sizeof(buffer));
       printf("##Received: '%d'\n",buffer);
   }
   return(0);    
}  

Share this post


Link to post
Share on other sites

printf("##Received: '%d'\n",buffer);

You're printing out buffer itself, which is a pointer. So what you're seeing is the memory address of the wherever you stored the incoming packets. Try

printf("##Received: '%u'\n",buffer[0]);

or if you prefer signed output

printf("##Received: '%d'\n",buffer[0]);

 

EDIT: there a message length hidden in there somewhere too. Look up yourself whether it's sent before or after the protocol number.

Edited by Grum

Share this post


Link to post
Share on other sites

DOH that was silly! thanks though it makes more sence now. im currently writing the stuff to split up the packet into size, protocol thing and message :blink:

 

Once the basic bot is done and ready to be made to do things do you think people would be insterested in the source? i might post it once its all tidy and commented.

Share this post


Link to post
Share on other sites
do you think people would be insterested in the source?

Heh...

I'm afraid a lot of people will be interested.

Share this post


Link to post
Share on other sites

im sorry to keep running back for help but i really cant figure this out.

what i have learned so far is message[0] is the protocol, message[2] and message[3] is the length and after that is the data.

 

The problem im having is the thing i had most problem with before, the length. (The one line i just copied and pasted was *((unsigned short int*)(temp + 1)) = packetlength + 3;)

 

So now im trying to get the message[2] message[3] into an integer but im not having much luck at all!

 

Also im wondering why cant it just use a normal int! its so much easier to understand.

Edited by kzar

Share this post


Link to post
Share on other sites
So now im trying to get the message[2] message[3] into an integer but im not having much luck at all!

unsigned short int len = *((unsigned short int*)(msg+1))

Also im wondering why cant it just use a normal int!  its so much easier to understand.

I wonder why normal ints are easier to understand than short unsigned ints. If anything, theyr're harder because of the two's complement negation.

Edited by Grum

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.

×