Jump to content


Photo

Faucet Networking


  • Please log in to reply
397 replies to this topic

#141 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 27 February 2012 - 07:50 PM

First, it would be very helpful to know the actual problem. What do you want to happen, and what actually does happen? It's not clear to me what the problem is from just your short explanation and looking at the code. You say you don't know what to write at a point that actually occurs twice in the code, and yet you wrote something there - so what's wrong with what you wrote?

Second, if you have relatively general questions that might not require deep knowledge of the extension, you can try asking them on StackOverflow. That could get you answers or at least ideas more quickly, and if nothing is forthcoming you can still get back here and just post a link to the question (so I can get all the delicious reputation points, hehe).
  • 0

#142 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 859 posts

Posted 28 February 2012 - 06:34 AM

This is quite specific to faucet networking;
I'd like a script to pass a packet received to many other sockets without having to make an individual script for each message id, or type of packet. For instance instead of writing, to pass a chat message;
message = read_string_delim(tcpsock);
chat_add(string(id)+": PARSED CHAT PACKET: "+message);

file = file_text_open_append(working_directory+"\Chatlog.txt");
file_text_write_string(file,name+": "+message);
file_text_writeln(file);
file_text_close(file);

buffer = buffer_create();
write_ubyte(buffer,8);
write_ubyte(buffer,position);
write_string_delim(buffer,message)

with (obj_player)
{
    if (id != other.id)
    {
        buffer_clear(tcpsock);
        write_ushort(tcpsock,buffer_size(other.buffer));
        write_buffer(tcpsock,other.buffer);
        socket_send(tcpsock);
    }
}
buffer_destroy(buffer);
I'd rather just call a script to pass this, ie: pass_packet(0,tcpsock,1,"");

It sounds stupid to ask for a script without any code given, which is why I posted my code (I have actually tried to make the script myself, but unsuccessfully and I'm just not sure why):
The rough script I was thinking of would go something like this:
with (other players)
{
                buffer_clear(tcpsock);
                write_ushort(tcpsock,buffer_size(argument1));
                write_ubyte(tcpsock,msgid);
                write_buffer(tcpsock,argument1);
                socket_send(tcpsock);
}
I've had many problems with this, the most recent try results in the client receiving a message id (the ubyte msgid line) of 0, when it's actually 10. There are probably more problems, but because I have almost no-one who is willing to test this for me I have to work around it by writing code for a player sending it back to himself. Obviously there are problems with this idea as clearing the buffer screws things up, but I worked around it. I'm just not sure the correct code to do this and don't have someone I can constantly send .gm81's to test with, modifying every single variable to figure out how to do it.

Edited by jon sploder, 28 February 2012 - 06:35 AM.

  • 0

#143 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 01 March 2012 - 12:37 AM

It sounds stupid to ask for a script without any code given, which is why I posted my code (I have actually tried to make the script myself, but unsuccessfully and I'm just not sure why)

I wasn't complaining that you provided code - that's a good thing, and shows that you are putting effort into figuring this out. It just wasn't clear to me what exactly the code was supposed to do, and how that differs from what actually happens.

Now let's see if I can help...

with (obj_player)
{
    if (id != other.id)
    {
        buffer_clear(tcpsock);
        write_ushort(tcpsock,buffer_size(other.buffer));
        write_buffer(tcpsock,other.buffer);
        socket_send(tcpsock);
    }
}

buffer_clear does nothing on sockets. I suspect this is a habit from the use of 39dll with a default buffer, where you have to clear that buffer first, then prepare your data in it and then copy it to the socket. The difference in FN is that socket_send does not make a copy of some buffer, it marks everything written to the socket so far as "ready for sending". In other words, everything written to a FN tcpSocket is sent exactly as it was written - socket_send only determines when that happens.

I'd rather just call a script to pass this, ie: pass_packet(0,tcpsock,1,"");
The rough script I was thinking of would go something like this:

with (other players)
{
                buffer_clear(tcpsock);
                write_ushort(tcpsock,buffer_size(argument1));
                write_ubyte(tcpsock,msgid);
                write_buffer(tcpsock,argument1);
                socket_send(tcpsock);
}


If your message format is still the same as in the example you posted a while ago, you need to add 1 to the message length, since you add the msgid seperately. Something else to look out for is that buffer_size only works for buffers as was already discussed (and yes, that's my fault :P).

However, you can work around that in several ways. For example, you can copy the message to an actual buffer first:
msgbuffer = buffer_create();
write_ubyte(msgbuffer, msgid);
write_buffer(msgbuffer,argument1);
with (other players)
{
                write_ushort(tcpsock,buffer_size(msgbuffer));
                write_buffer(tcpsock,msgbuffer);
                socket_send(tcpsock);
}
buffer_destroy(msgbuffer);

Alternatively, you can use
max(socket_receivebuffer_size(argument1), buffer_size(argument1))
to determine either the size of a buffer or the size of the receivebuffer of a socket - each function returns 0 if the wrong type of object handle is passed, so the maximum will be the result of the function that worked.

This is definitely an ugly spot in the API, but I can't think of a good solution right now that doesn't break compatibility. The best idea so far is to make socket_receivebuffer_size work on buffers as well, but that does not fit the function name well.

Edited by Medo42, 01 March 2012 - 12:37 AM.

  • 0

#144 wnsrn3436

wnsrn3436

    GMC Member

  • GMC Member
  • 134 posts
  • Version:GM8

Posted 01 March 2012 - 11:23 AM

What is plan of version 2?
I expect that version.

My point of view, the buffer should have features similar to ds_list. ;)
For example.
buffer_insert (ds_list_insert), buffer_replace, buffer_delete.
You think all of this, should consider.

And I have a ideas for a bit function.
Variable=1234
Variable=new_bit_function(Variable)
Results. Variable="10011010010"

What about you?

Ps. My FNs script, what do you think? (FN Simple Scripts)

Edited by wnsrn3436, 01 March 2012 - 11:38 AM.

  • 0

#145 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 859 posts

Posted 05 March 2012 - 06:53 AM

Alright, thanks Medo that solves a few problems and shortened some code, but I've just got such a massive amount of problems that seem endless, I decided to upload the source online. All the program is so far is chat + login/reg and primitive drawing of lines (mouse). The problem being is that when I test locally I can't replicate half the bugs experienced when not local.

The problems I'd really appreciate you take a quick look at:
Is my general online method correct for non-local testing?
Why does my pass_packet script continue to screw up? You can see that it doesn't screw up if, you take the 'drawkit' script in the Server.gm81 and uncomment the code commented, and comment out the pass_packet 1st line.
Anything online with tcp.

What I don't care about at all:
Problems within the actual chat system drawing etc, or line drawing (drawkit offline stuff).
Anything offline.
UDP (it's not really implemented anyway)

My sources: http://www.box.com/s...nb18mico4npo113
  • 0

#146 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 12 March 2012 - 09:25 PM

What is plan of version 2?
I expect that version.

Don't. So far it's just a collection of ideas, not completely thought through yet, and at this point I won't even promise that it will eventually be made (though I still plan to do it).

Alright, thanks Medo that solves a few problems and shortened some code, but I've just got such a massive amount of problems that seem endless, I decided to upload the source online. All the program is so far is chat + login/reg and primitive drawing of lines (mouse). The problem being is that when I test locally I can't replicate half the bugs experienced when not local.

The problems I'd really appreciate you take a quick look at:
Is my general online method correct for non-local testing?
Why does my pass_packet script continue to screw up? You can see that it doesn't screw up if, you take the 'drawkit' script in the Server.gm81 and uncomment the code commented, and comment out the pass_packet 1st line.
Anything online with tcp.

What I don't care about at all:
Problems within the actual chat system drawing etc, or line drawing (drawkit offline stuff).
Anything offline.
UDP (it's not really implemented anyway)

My sources: http://www.box.com/s...nb18mico4npo113

The thing is, I will not help you tackle a massive ammount of problems that seems endless. I have my own problems to work on, and while I can spare some time to answer the occasional question, I will not spend hours digging into your code to find unspecified bugs.

To help you isolate problems in networking code, in particular in non-local testing, I can once again point you to Wireshark. That tool allows you to capture the network traffic from and to your PC, so that you can observe exactly what happens in your connections and narrow down where a particular bug might be.
  • 0

#147 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 12 March 2012 - 09:39 PM

Version 1.4.1 has been released.

It fixes a crash and potential security vulnerability triggered by using game_restart(). It is strongly recommended to update to this new version.

Download here.
  • 0

#148 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 859 posts

Posted 13 March 2012 - 06:45 AM

By the way; I direct that post to everyone viewing, rather than just Medo.
  • 0

#149 Ronchon le Nain

Ronchon le Nain

    GMC Member

  • GMC Member
  • 87 posts
  • Version:GM8

Posted 13 March 2012 - 11:29 PM

I have a weird bug where i have a message (A) that is not processed ( whether if he's not sent by client or not received by server is unclear ) until a 2nd one of any other kind (B) is sent, whatever the delay between them.
Meaning if i send A only, nothing happens : nothing is ever received by server.
If i send A twice, 2 A are areceived.
If i send A then B , A then B are received.
If i send B , B is received...
I have no idea of what's going on. It's like my first A message is queued up somewhere, but only when it's a A.

Posted Image

Edited by Ronchon le Nain, 15 March 2012 - 07:09 PM.

  • 0

#150 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 15 March 2012 - 11:17 PM

I have a weird bug where i have a message (A) that is not processed ( whether if he's not sent by client or not received by server is unclear ) until a 2nd one of any other kind (B) is sent, whatever the delay between them.
Meaning if i send A only, nothing happens : nothing is ever received by server.
If i send A twice, 2 A are areceived.
If i send A then B , A then B are received.
If i send B , B is received...
I have no idea of what's going on. It's like my first A message is queued up somewhere, but only when it's a A.

Posted Image

The extension definitely doesn't look at the content of your messages, so if A and B are the same length there must be something different in your code between them. Once again I recommend Wireshark to find out when A is actually sent, to see whether the problem is on the sending or the receiving end.
  • 0

#151 True Valhalla

True Valhalla

    ಠ_ಠ

  • Retired Staff
  • 4938 posts
  • Version:GM:Studio

Posted 16 March 2012 - 01:23 AM

How stable is this DLL in general? I've been using 39dll with my project Myriad Online for over 2 years now - both with my GM client and C++ server - and to be honest it hasn't presented a lot of issues that I've noticed, though I do understand that the extension is flawed and I'm always looking for something better to upgrade to.

The only problem I have with the idea of transitioning to a new networking DLL is that there may be actual critical bugs, and perhaps the developer does not plan to continue support for the extension. 39dll might be old and poorly coded, but it is robust enough to get the job done.

I want to change, I am just not confident I'd be making the right choice.
  • 0

#152 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 16 March 2012 - 10:26 AM

How stable is this DLL in general? I've been using 39dll with my project Myriad Online for over 2 years now - both with my GM client and C++ server - and to be honest it hasn't presented a lot of issues that I've noticed, though I do understand that the extension is flawed and I'm always looking for something better to upgrade to.

The only problem I have with the idea of transitioning to a new networking DLL is that there may be actual critical bugs, and perhaps the developer does not plan to continue support for the extension. 39dll might be old and poorly coded, but it is robust enough to get the job done.

I want to change, I am just not confident I'd be making the right choice.

It has been used in a few games, one of them Gang Garrison 2 where it was introduced about a year ago, and which has up to 50 people playing at the same time on a typical day. Of course, as the saying goes, every nontrivial piece of software has bugs. If I count correctly, there have been 5 bugs found in the extension since version 1.0. Three of those were reported by users, I noticed the other two myself. More importantly though, they were all quickly squashed.

I plan to continue supporting Faucet Networking in the forseeable future, at least for bugfixes (and I will continue supporting version 1.x this way if/when version 2 gets made).
  • 0

#153 True Valhalla

True Valhalla

    ಠ_ಠ

  • Retired Staff
  • 4938 posts
  • Version:GM:Studio

Posted 16 March 2012 - 11:21 AM

Alright, well it sounds like it might be worth looking into. I'll give it some thought.
  • 0

#154 starfire_64

starfire_64

    Galactic Flame

  • GMC Member
  • 114 posts
  • Version:GM:Studio

Posted 17 April 2012 - 09:28 PM

Can this GEX be used to download files via HTTP?
  • 0

#155 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 17 April 2012 - 11:14 PM

Can this GEX be used to download files via HTTP?

Yes, but if that is everything you need it for, it will be easier to use a dedicated HTTP extension, e.g. Maarten Baert's Http Dll 2 or the Download Manager extension from h0bbel.

That said, it is not very difficult to download files "manually" with Faucet Networking, especially if you are happy with using HTTP 0.9 - just send "GET <url><crlf>" to your server and read everything it sends to you until it closes the connection. I am not sure if all servers allow you to use this old version of HTTP though, especially for downloading binary data, but I had no problems with it so far.
  • 0

#156 starfire_64

starfire_64

    Galactic Flame

  • GMC Member
  • 114 posts
  • Version:GM:Studio

Posted 18 April 2012 - 11:23 PM

Yes, but if that is everything you need it for, it will be easier to use a dedicated HTTP extension, e.g. Maarten Baert's Http Dll 2 or the Download Manager extension from h0bbel.

Right. I am going to make an MMO with this .GEX.

Edited by starfire_64, 18 April 2012 - 11:23 PM.

  • 0

#157 SapperEngineer

SapperEngineer

    GMC Member

  • GMC Member
  • 110 posts
  • Version:Mac

Posted 12 May 2012 - 12:47 AM

Hayo! It's me again after a long time! I'm afraid I need a little more help.

I decided to write an 'actual' server this time rather than have the client host for one other player. It functions fine.. with a few problems.

I use this code:


while (socket_receivebuffer_size(serversocket) >= 6)
{
tcp_receive(serversocket, 6)
show_message("Recv'd 6 bytes")
startbyte = read_short(serversocket)
messagetype = read_short(serversocket)
show_message(string(messagetype))
....etc


And it says 'Recv'd 6 bytes' and then when it shows the startbyte message, it has something as of '-4072' or something similar. When I put
show_message('')
before the while loop, it works charmily. I think it has to wait a few seconds before it can actually read anything.. Very strange behavior. Is this a bug, or am I missing something?

Thanks for your help in the past! -SapperEngineer
  • 0

#158 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 12 May 2012 - 07:44 AM

You seem to be using socket_receivebuffer_size as if it tells you how much data you can receive at the moment. However, what it tells you is how much you have received. That means the tcp_receive may or may not find its 6 bytes - and if it doesn't, the receive buffer will be empty afterwards. Then when you try to read your two shorts, you will get undefined results.

Instead of trying to find out whether there is enough data, just use tcp_receive - it already checks that and only moves the data into the receivebuffer if there is enough:

while (tcp_receive(serversocket, 6))
{
show_message("Recv'd 6 bytes")
startbyte = read_short(serversocket)
messagetype = read_short(serversocket)
show_message(string(messagetype))
....etc

Edited by Medo42, 12 May 2012 - 07:45 AM.

  • 0

#159 SapperEngineer

SapperEngineer

    GMC Member

  • GMC Member
  • 110 posts
  • Version:Mac

Posted 12 May 2012 - 05:16 PM

Thanks for the speedy response.

I have this:

show_message("Asking for list")
write_short(serversocket, MSG_STARTBYTE)
write_short(serversocket, MSG_ASKFORLIST)
socket_send(serversocket)


while (tcp_receive(serversocket, 6))
{
show_message("Recv'd 6 bytes")
startbyte = read_short(serversocket)
messagetype = read_short(serversocket)
show_message(string(messagetype))
}

Although it just displays "Asking for list" and then proceeds to do nothing and chew up my CPU.

I've even got it so the server displays "Sending playerlist" (which it does). Although, if I put a show_message('') straight before the
while(tcp...)
it works fine. Sorry if I'm being somewhat of a pest, this is just quite the perplexing problem to me.

Edited by SapperEngineer, 12 May 2012 - 05:17 PM.

  • 0

#160 Medo42

Medo42

    GMC Member

  • GMC Member
  • 226 posts

Posted 12 May 2012 - 05:32 PM

You are sending a request to the server and immediately check for a response. It is very likely that the server did not send a reply yet when you call tcp_receive, so you never enter the while-loop. Remember, tcp_receive does not wait for anything, if no data is there yet it just returns false.

Even if you wait for the first data from the server before entering the loop, it is not a good idea to use "no more data received" to detect the end of the list you are expecting, because it is also possible that the remaining list entries just did not arrive yet. I'd recommend to send the number of list entries before the list, so the receiver knows when all of them have arrived.

Edited by Medo42, 12 May 2012 - 05:33 PM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users