Jump to content


Photo

Faucet Networking


  • Please log in to reply
630 replies to this topic

#121 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 13 February 2012 - 06:17 AM

Excellent, very excited for the new version. Thanks a lot Medo!

EDIT 2: The problem to the below might be due to this: For some reason my client can only send a message in it's create event: right after I use tcp_connect to get a tcpsocket handle. No other messages can be sent outside this event, unless immediately beforehand I reset the tcpsocket handle with another tcp_connect... Any ideas what I'm doing wrong or how to fix it? I'll post the code if you want it but there is a fair bit of junk in it to fill in reminders for myself for later work.

Edit: I have the scripts:
/*
write_string_delim(socket,string);
argument0: socket
argument1: string will be given a delimiter automatically
*/
write_ushort(argument0,string_length(argument1));
write_string(argument0,argument1);
and
/*
read_string_delim(socekt);
argument0: socket
*/
var length, string;
length = read_ushort(argument0);
string = read_string(argument0,length);
return string;

I'm not sure what's going on because the code:
write_string_delim(argument4,mac_addrs());
will not allow the socket to send it's data, but this returns no errors via the extension precaution function... I'm unsure whether it is the mac address function somehow screwing it up or my code, although it must be noted that my write_string_delim works for every other string I've tested. show_message(get_macadr) returns a proper string mac address so I'm stumped.

Edited by jon sploder, 13 February 2012 - 07:58 AM.

  • 0

#122 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 13 February 2012 - 10:03 PM

Without further info there is not much I can say about this. It seems unlikely that the mac_addrs() function would cause sockets to misbehave, because the code for mac_addrs() has no interconnection at all to any other code in the library except for being linked into the same dll.

As for what does go wrong, you could use Wireshark to figure out what actually happens between client and server. That should give you a good starting point for narrowing down the problem in the code.
  • 0

#123 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 14 February 2012 - 08:30 AM

I found the problem; I was accepting sockets per step in the server, so if I made it only accept once the connection worked. I remember I did this for 39dll and it worked fine (was required). Where am I meant to put the acceptor handle code? (It's not every step)
Current snippet from the code that didn't work:

tcpsock = socket_accept(acceptor);
        datagram = tcp_receive_available(tcpsock);
        if (datagram)
        {
            //check to see if anyone is connecting from the 'wrong' port
            if (socket_local_port(tcpsock) != global.tcpport)
            {
                socket_destroy_abortive(tcpsock); //ungracefully close the socket;                
                chat_add("___someone connected from the wrong port."+string(socket_remote_port(tcpsock)));
            }
            var msgid;
            msgid = read_ubyte(tcpsock);        
            script_execute(global.tcpscript[msgid]);
        }
Changed to :
if (!tcpsock) {tcpsock = socket_accept(acceptor);}
To work.

Edited by jon sploder, 14 February 2012 - 08:31 AM.

  • 0

#124 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 14 February 2012 - 06:41 PM

There are several things wrong with this code:
- You attempt to accept a new socket every step and overwrite your old socket with that. I have no idea what you are trying to do there. Typically, a TCP server uses one socket for every connected client, so if you want to support multiple clients, you need to keep track of the socket for each one seperately.
- The code assumes that tcp_receive_avaliable will give you a complete message of some sort - but that's not guaranteed. It will just give you *some* number of bytes. You should not make assumptions about how and where TCP packets will be split up or combined, otherwise your protocol will break under load and in real use, even if you get your data exactly in the neat packets you sent if you test on a LAN.
- The check whether someone is connecting on/from (seems to be inconsistent) the wrong port is useless. If it is supposed to check whether the local port is correct, that can never fail because sockets can't accept connection attempts to a different port. If it's supposed to check if the remote port is correct, you'll have a hard time using this server with Faucet Networking because it has no way to specify a source port with tcp_connect. It's just something that is almost never needed (in fact I can't think of a good reason why a protocol would need it).
  • 0

#125 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 15 February 2012 - 07:14 AM

Surely I must always look out for new connections, and the way to do it is constantly accept new sockets? My server has one object to do this (handle login and registration) and makes a new object for each new connection, and remembers the 'tcpsock' variable on receiving a messageid for login/reg... sorry my code wasn't very revealing because the making a new object and remembering tcpsock is in the script_execute part.

Would this code be a better server loop for receiving?
while (tcp_receive(tcpsock,bytes))
{
    if (byteisheader)
    {
        bytes = read_ushort(tcpsock);
        byteisheader = 0;
    }
    else
    {
        var msgid;
        msgid = read_ubyte(tcpsock);
        chat_add("___msg debug id "+string(msgid));
        if (variable_global_array_get('tcpscript',msgid))
        {
            script_execute(global.tcpscript[msgid]);
        } else {chat_add("___a message id was sent that the server does not know");} //debug
        byteisheader = 1;
        bytes = 2;
    }
}
(tried to be similar to your example).

I still am not sure where to put the tcpsock acceptor definition though...

EDIT: Nevermind for now, I just saved all previous sockets into a loop. I'm not really confident with anything I write in this though. If, when I'm done, I post the source to my first attempt to use this extension could you have a quick look at try and tell me any ineffeciencies or things that just plain don't work (like before with the remote_port thing... I assumed that was what it was for so I just put it in)? It'd be pretty helpful for me and others, as I'll probably make most of the same errors that other people used to 39dll will make.

Edited by jon sploder, 16 February 2012 - 06:37 AM.

  • 0

#126 wnsrn3436

wnsrn3436

    GMC Member

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

Posted 16 February 2012 - 12:16 AM

In my opinion. When you upload your source will be processed quickly.
  • 0

#127 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 16 February 2012 - 07:18 AM

Just checking with you medo, does this seem reasonable:

tcpsock = socket_accept(acceptor);
if (tcpsock >= 0)
{
    sockets += 1;
    socket[sockets] = tcpsock;
    chat_add("new client(socket): "+string(tcpsock)+". total sockets: "+string(sockets));
}
var i;
for (i = 1; i <= sockets; i += 1)
{
    while (tcp_receive(socket[i],bytes))
    {
        chat_add('received a byte');
        if (byteisheader)
        {
            bytes = read_ushort(socket[i]);
            byteisheader = 0;
        }
        else
        {
            var msgid;
            msgid = read_ubyte(socket[i]);
            chat_add("___msg debug id "+string(msgid));
            if (variable_global_array_get('tcpscript',msgid))
            {
                script_execute(global.tcpscript[msgid]);
            } else {chat_add("___a message id was sent that the server does not know");} //debug
            byteisheader = 1;
            bytes = 2;
        }
    }
    //chat_add("for: "+string(i)+" "+string(socket[i]));
}

  • 0

#128 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 16 February 2012 - 03:11 PM

Just checking with you medo, does this seem reasonable:

tcpsock = socket_accept(acceptor);
if (tcpsock >= 0)
{
    sockets += 1;
    socket[sockets] = tcpsock;
    chat_add("new client(socket): "+string(tcpsock)+". total sockets: "+string(sockets));
}
var i;
for (i = 1; i <= sockets; i += 1)
{
    while (tcp_receive(socket[i],bytes))
    {
        chat_add('received a byte');
        if (byteisheader)
        {
            bytes = read_ushort(socket[i]);
            byteisheader = 0;
        }
        else
        {
            var msgid;
            msgid = read_ubyte(socket[i]);
            chat_add("___msg debug id "+string(msgid));
            if (variable_global_array_get('tcpscript',msgid))
            {
                script_execute(global.tcpscript[msgid]);
            } else {chat_add("___a message id was sent that the server does not know");} //debug
            byteisheader = 1;
            bytes = 2;
        }
    }
    //chat_add("for: "+string(i)+" "+string(socket[i]));
}

Yes, that looks better, but I still see a problem: byteisheader and bytes are shared between all sockets, so if the last thing read from one socket is the header (again, unlikely on a LAN) the next socket will attempt to receive a message corresponding to the header of the previous socket. To make this work, you need byteisheader and bytes for every socket. In Gang Garrison 2 every client has its own object (Player) which holds the socket and the current protocol state (commandReceiveState and commandReceiveExpectedBytes - basically the same as your byteisheader and bytes). I do realize that it's awkward to manually keep track of this state, and that it is something many games need. Even 39dll has some support for automating this with its message formats, so this is definitely something I want to address some time. No promises on when that will happen though.

Edited by Medo42, 16 February 2012 - 03:12 PM.

  • 0

#129 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 19 February 2012 - 02:40 AM

Thanks.

write_buffer_to_file() doesn't work with sockets as the buffer for me. Can you replicate this? And/Or buffer_size doesn't work with sockets. My code to show this is:

var buffer;
buffer = buffer_create();

write_ubyte(buffer,8);
write_string_delim(buffer,argument1);
chat_add("buffer size: "+string(buffer_size(argument0)));
buffer_clear(argument0);
write_ushort(argument0,buffer_size(buffer));
write_buffer(argument0,buffer);
chat_add("buffer size: "+string(buffer_size(argument0)));
socket_send(argument0);

buffer_destroy(buffer);
Both times it returns a buffer size of 0. See if you can replicate this yourself.

Edited by jon sploder, 19 February 2012 - 02:49 AM.

  • 0

#130 wnsrn3436

wnsrn3436

    GMC Member

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

Posted 19 February 2012 - 10:08 AM

Thanks.

write_buffer_to_file() doesn't work with sockets as the buffer for me. Can you replicate this? And/Or buffer_size doesn't work with sockets. My code to show this is:

var buffer;
buffer = buffer_create();

write_ubyte(buffer,8);
write_string_delim(buffer,argument1);
chat_add("buffer size: "+string(buffer_size(argument0)));
buffer_clear(argument0);
write_ushort(argument0,buffer_size(buffer));
write_buffer(argument0,buffer);
chat_add("buffer size: "+string(buffer_size(argument0)));
socket_send(argument0);

buffer_destroy(buffer);
Both times it returns a buffer size of 0. See if you can replicate this yourself.


The socket is different from the common buffer.
The socket send/receive buffers is divided.
In my opinion. You should use the following functions.

socket_sendbuffer_size(socket) : size
socket_receivebuffer_size(socket) : size

Edited by wnsrn3436, 19 February 2012 - 10:09 AM.

  • 0

#131 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 19 February 2012 - 02:05 PM

I can see that I made some mistakes there. First, I don't think there's an actual reason why write_buffer_to_file() shouldn't work on sockets (though if you look at the documentation, it explicitly says "buffer", so it's at least consistent).

Second, it was possibly not a good idea at all to have the write/read functions accept sockets directly, because this makes sockets work in some places where buffers work, but not in others where you might expect it, and where it does work the semantics are slightly different, all of which makes this feature somewhat confusing. It is easier in some ways, but more complex. And while it does save some code in small examples, if I consider Gang Garrison most of the networking uses explicit buffers anyway or could be changed to use them with very little extra code.

Other things that I'm considering to change include
- the lenient behavior regarding e.g. invalid handles (replaced by some way of logging / error handling)
- the names of the read/write functions to reduce confusion of type lenght (read_ushort->read_u16, read_double->read_f64)
- remove the buffer endian awareness (replaced by explicit-endian read/write functions, e.g. read_u16l, read_u16b). Not sure what to make the default there; big-endian is the "standard" network byte order, but little-endian is what 39dll does. Maybe there could be no default at all and you always have to specify l/b... at least it would force people to consider what they are doing, and if you stick with one standard it shouldn't take any mental effort to always add the same suffix.

Don't worry, those are just ideas for version 2, aka the great big redesign. If/when I get around to working on that, version 1 will still be supported.
  • 0

#132 Ronchon le Nain

Ronchon le Nain

    GMC Member

  • GMC Member
  • 96 posts
  • Version:GM8

Posted 19 February 2012 - 08:18 PM

Greatings.
I'm now testing Faucet. Congratulations for the help file, it's really helpfull and well explained.
One small question : is there an equivalent to buffer_bytes_left , but for the receive buffer of a socket, to know how many bytes are still remaining to be read ?
  • 0

#133 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 19 February 2012 - 09:11 PM

Thanks wrsrn and Medo, yeah I saw that it said explicitly buffer but assumed because some other buffer functions can be substituted successfully that it might be do-able. Those ideas seem interesting.
  • 0

#134 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 19 February 2012 - 09:59 PM

Greatings.
I'm now testing Faucet. Congratulations for the help file, it's really helpfull and well explained.
One small question : is there an equivalent to buffer_bytes_left , but for the receive buffer of a socket, to know how many bytes are still remaining to be read ?

Thanks. I just checked in the code, there isn't. It's probably just something that never came up before.
I just changed the code around a bit so that buffer_bytes_left, buffer_set_readpos, write_buffer_to_file and append_file_to_buffer now all accept sockets too. This means udp_send is one of the few functions remaining which accept buffers but not all sockets - unfortunately, it already has a particular meaning for being called on udp sockets with very different semantics. How did I get the idea again that this kind of punning was a good idea? :P
The only other remaining functions which don't accept sockets are those where the meaning would be unclear: buffer_destroy, buffer_clear and buffer_size.

Edited by Medo42, 19 February 2012 - 10:00 PM.

  • 0

#135 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 19 February 2012 - 10:22 PM

Here you go: Version 1.4
- Enabled more buffer functions to use sockets: buffer_bytes_left, buffer_set_readpos, write_buffer_to_file and append_file_to_buffer

Download
  • 0

#136 wnsrn3436

wnsrn3436

    GMC Member

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

Posted 19 February 2012 - 11:53 PM

Right.
I think it would eliminate the confusion that feature.
The new version is very good.

Also, I should hope.
1. I think you need to add more files to function.
2. Encryption function of the buffer.
3. Whether the message is received. (function).
4. Get my ip. (Lan ip, Wan ip, ipv4, ipv6).
5. Get my hostname.

In the case of 3. it useful for sending exit messages.
The most similar code :
write_byte(socket, 0)
socket_send(socket)
while(socket_sendbuffer_size(socket)){} // Whether the message is received.
socket_destroy(socket)

In the case of 4.
The most similar code *Script* get_my_ip(0=Lan ip/1=Wan ip) :
/*Do not use it!
Obtaining WAN IP is unstable.*/
if !argument0{return mplay_ipaddress()} //Lan ip
else
{
    var skv_soket, skv_string, skv_buffer;
    skv_soket=tcp_connect("whatismyip.org", 80)
    if socket_has_error(skv_soket){socket_destroy(skv_soket); return ""}
    write_string(skv_soket, "GET / HTTP/1.0"+chr(13)+chr(10)+chr(13)+chr(10))
    socket_send(skv_soket)
    skv_buffer=buffer_create()
    while(!tcp_eof(skv_soket))
    {
        sleep(10)
        tcp_receive_available(skv_soket)
        write_buffer(skv_buffer, skv_soket)
    }
    skv_string=read_string(skv_buffer, buffer_size(skv_buffer))
    skv_string=string_delete(skv_string, 1, string_pos(chr(13)+chr(10), skv_string)+2)
    skv_string=string_delete(skv_string, 1, string_pos(chr(13)+chr(10), skv_string)+2)
    socket_destroy(skv_soket)
    buffer_destroy(skv_buffer)
    return skv_string
    //Wan ip
}

Edited by wnsrn3436, 03 March 2012 - 08:40 AM.

  • 0

#137 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 20 February 2012 - 08:02 AM

1. I think you need to add more files to function.
2. Encryption function of the buffer.
3. Whether the message is received. (function).
4. Get my ip. (Lan ip, Wan ip, ipv4, ipv6).
5. Get my hostname.

In the case of 3. it useful for sending exit messages.
Methods now available. :

while(socket_sendbuffer_size(socket)){}

You think I need to? That... doesn't quite sound right.

Anyway, as for 1 and 2 I'd prefer not to add more features not directly related to networking and rather address these things in version 2, which will support some standard for efficiently handing binary data from one extension to another, so that this kind of functionality can be provided by other extensions.

As for 3, this is something the socket API simply does not provide as far as I am aware. However, a small extension to the semantics of socket_sendbuffer_size() would allow you to determine if everything has at least been sent in the way you show. Actually what it would indicate is even weaker, i.e. if everything has been written to the operating system for sending, but that should be enough to ensure everything is sent on exit. Currently, this approach might work, but I'd have to make sure and make the specification more clear on that point.

4. is partially covered by socket_local_ip. Note that your machine can have several IPs, so just asking for "the LAN IP" does not always have a single answer. There is a way to enumerate the IP configuration of the networking adapters, but I think there is simply not much need for providing it (please give a specific example of what you want to achieve). There is no lowlevel way to determine your WAN IP.

5. That would be trivial to add, but what is it needed for?
  • 0

#138 wnsrn3436

wnsrn3436

    GMC Member

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

Posted 20 February 2012 - 01:43 PM

4. is partially covered by socket_local_ip. Note that your machine can have several IPs, so just asking for "the LAN IP" does not always have a single answer. There is a way to enumerate the IP configuration of the networking adapters, but I think there is simply not much need for providing it (please give a specific example of what you want to achieve). There is no lowlevel way to determine your WAN IP.

5. That would be trivial to add, but what is it needed for?


​I'm just trying to get IP address with lookup function using hostname​. :sweat:

Ps. socket_local_ip->socket_remote_ip?

Edited by wnsrn3436, 20 February 2012 - 01:44 PM.

  • 0

#139 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 posts

Posted 21 February 2012 - 07:37 PM

​I'm just trying to get IP address with lookup function using hostname​. :sweat:

Well, I guess that's a way to do this :P

Ps. socket_local_ip->socket_remote_ip?

I'll be happy to answer questions, but please make the effort of asking them in plain english.
  • 0

#140 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 917 posts

Posted 27 February 2012 - 07:37 AM

Medo, I'm trying to write a script that passes a message on to all other clients, ie ClientA -> Server, Server -> Client[B,C,D...].
My script: (for now, only assume tcp, I'm not using udp but that's old code just for when I do include both protocols)

/*
pass_packet(all | individual_socket,source_socket,protocol,ip);
argument0: all being 0, otherwise an individual socket is assumed (tcp or udp)
argument1: the socket or buffer being copied
argument2: udp/tcp, udp being 0, tcp being 1
argument3: if script is not called from obj_player or obj_server, this argument specifies ip for individual_socket
*/

if (argument3 != "")
{
    var ip;
    ip = argument3;
}

//pass on to all other players
if (argument0 == 0)
{
    with (obj_player)
    {
        if (id != other.id) //I know this won't work locally, but I've taken that into consideration when testing
        {
            if (argument2) //send tcp
            {
                chat_add("passing a tcp packet from "+string(argument1)+" to "+string(tcpsock));
                //write size of packet bytes and then message id etc.
                write_buffer(tcpsock,argument1);
                socket_send(tcpsock);
            }
            else //send udp
            {
                udp_send(argument1,ip,global.udpport);
            }
        }
    }
}
//pass on to an individual socket
else
{
    if (argument2) //send tcp
    {
        write_buffer(argument0,argument1);
        socket_send(argument0);
    }
    else //send udp
    {
        udp_send(argument1,ip,global.udpport);
    }
}

I know this isn't correct, I wrote it a while ago (several pages of explanations ago), but I'm not sure how I should write it after the 'if (argument2) //send tcp' segment... could you help me out with an example script to pass a packet on from one players receiving tcp socket, to another players sending tcp socket.
  • 0

#141 Medo42

Medo42

    GMC Member

  • GMC Member
  • 308 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
  • 917 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
  • 308 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
  • 149 posts
  • Version:GM:Studio

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
  • 917 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
  • 308 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
  • 308 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
  • 917 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
  • 96 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
  • 308 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




1 user(s) are reading this topic

1 members, 0 guests, 0 anonymous users