Jump to content

Monkuar

Members
  • Posts

    987
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Monkuar

  1. You could of answered that question yourself by looking at the php documentation for the functions used in the code you posted.

     

    Huh? The documentation is as follows:

     

    bool[/size] [/size]socket_getpeername[/size] ( [/size]resource $socket[/size] , [/size]string &$address[/size] [, [/size]int &$port[/size] ] )[/size]

     

     

    And Address:

    If the given socket is of type AF_INET or AF_INET6, socket_getpeername() will return the peers (remote) IP address in appropriate notation (e.g. 127.0.0.1 or fe80::1) in the address parameter and, if the optional port parameter is present, also the associated port.

    If the given socket is of type AF_UNIX, socket_getpeername() will return the Unix filesystem path (e.g. /var/run/daemon.sock) in theaddress parameter

    This function is returning '1', which is meant to be localhost I'm using? That doesn't make sense to me, it should be returning the address the documentation states. 

     

    This function literally is misinterpreted and doesn't actually work as intended.

     

    // fetch client IP as integer
    $clientIP = '';
    $clientIP2 = '';
    $result = socket_getpeername($client, $clientIP);
    $clientIP = ip2long($clientIP);
     

    How does $clientIP return my address (my up) when the original variable is SET TO = ''? (BLANK, NADA, ZIP).

     

    I can see how the $result works, because $client is linked to my websocket message:

    $client = socket_accept($wsRead[0]);
    But you guys are not getting my original point:

     

    // listen socket changed
    						$client = socket_accept($wsRead[0]);
    						if ($client !== false) {
    							// fetch client IP as integer
    							$clientIP = '';
    							$clientIP2 = '';
    							$result = socket_getpeername($client, $clientIP);
    							$clientIP = ip2long($clientIP);
    This is not making sense, $clientIP variable is SET to '', but it's still returning my ip adresss (which is fine, from $client [the websocket message buffer], but how is ip2long reading a $clientIP variable that is SET to = '' and returning localhost?

     

    The only thing that I can get from this is that:

     

    The $clientIP variable that is passed in socket_getpeername is somehow magically storing the ip address? Lol what? How is that possible? If that is true because it's being passed by socket_getpeername, where the hell does it say that $clientIP will be stored the IP? No where in the php documentation does it say that.

  2.  

    Allow me to make an assumption without checking the manual on any of it:

    * socket_getpeername() is taking it's second parameter by reference. Thus, there should be something to reference (a zero-length string)

     

     

    Okay, can accept that.

     

     

    // fetch client IP as integer
    $clientIP = '';
    $test = '';
     
    $result = socket_getpeername($client, $clientIP);
    $clientIP = ip2long($clientIP);
     
     
     
    //This returns 1
    $result2 = socket_getpeername($client, $test);
     
    Now #result2 is returning "1". What does 1 mean? True? Or 1 because the socket is being run on localhost?
  3. This code was extracted from phpwebsockets server from google:

     

    All I am trying to do is grab the  USERS IP ADDRESS.
     
    $clientIP is returning:
     
    "2130706433"
     
    Which makes NO SENSE WHATSOEVER (I'm on localhost) AND WHY is the $clientIP variable SET TO NOTHING before the $result? How the fuck does it get 2130706433 from $clientIp when the variable is fucking set to = ''? That makes ABSOLUTELY no sense whatsoever. Then it gets passed to socket_getpeername? The SECOND parameter for that NEEDS A HOST, HOW can the HOST be = ''? Are you telling me this phpwebsockets server is for localhost development only? BECAUSE if that is the case, EACH new connection will have the same $clientIP = ''; THAT MAKES NO SENSE? It should be the USERS REMOTE IP ADDRESS??.  I know ip2long is doing something and converting it. All I want is the regular IPV4 ADDRESS, is it really that hard to ask?
     
     
    Literally, how hard is it to grab the users ip from the main socket connection? This is killing development time, what a fucking joke. I am infuriated.  Should have never started using php as a websocket server.
    // fetch client IP as integer
    $clientIP = '';
    $result = socket_getpeername($client, $clientIP);
    $clientIP = ip2long($clientIP);
     
     
     
    $clientIP2 = 'test';
     
    if ($result !== false && $wsClientCount < WS_MAX_CLIENTS && (!isset($wsClientIPCount[$clientIP]) || $wsClientIPCount[$clientIP] < WS_MAX_CLIENTS_PER_IP)) {
    wsAddClient($client, $clientIP);
    }
  4. 
    

    PHP Websockets Rate limiter (Thanks to @Kicken for the help)

     

    How do I setup let's say... no more than 5 requests per second?  Any idea?

     
    
    // anti flood protection
    if (isset($users[$clientID]['last_session_request'])) {
    if($users[$clientID]['last_session_request'] > ''.microtime(true).'' - 1){
    // users will be redirected to this page if it makes requests faster than 1 seconds
    echo "Limit Reached... Simmer down!";
    wsClose($clientID);
    }else{
     
     
    }
    $users[$clientID]['last_session_request'] = microtime(true);
    }
    
     
    
  5. Sounds like you have a bug in your wsBuildClientFrame function which is causing it to go into a recursion loop. You should address that issue before adding rate limiting.

     

    To add rate limiting, you count the # of requests along with keeping track of a timestamp. On each request compare the current # of requests to the # at the last timestamp and see if it's above your limit. If so, deny the request.

     

    Something like this

    //$lastTimestamp = timestamp of last check
    //$lastCount = whatever $count was at last check
    $now = time();
    $count++; 
    $timeDiff = $now - $lastTimestamp;
    if ($timeDiff > 1){ //Ensure timestamps have changed
       $countDiff = $count - $lastCount;
       $lastTimestamp = $now;
       $lastCount = $count;
    
       if ($countDiff/$timeDiff > 5){ //if more than 5 requests per second
          denyRequest();
       }
    }
    

     

     

    Sorry to bump this thread, but I got a working version:

    function wsOnMessage($clientID, $message, $messageLength, $binary) {
    global $servername, $dbuser, $dbpassword, $dbname, $users, $db;
     
    // anti flood protection
    if($_SESSION['last_session_request'] > time() - 1){
    // users will be redirected to this page if it makes requests faster than 2 seconds
    echo "Limit Reached... Simmer down!";
    return false;
    }else{
     
    echo $_SESSION['last_session_request'];
    }
    
    

    I got a working version working here:

     

    My question is: That return false works but it will stop the whole script? Which if other users are using will stop them as well right? How do I only target the specific client and user instead?

     

    Also, should I use microtime instead? 

     

    You know, I can use "wsClose($clientID);" to kick them off. But what's stopping them from just refreshing?

  6. Sounds like you have a bug in your wsBuildClientFrame function which is causing it to go into a recursion loop. You should address that issue before adding rate limiting.

     

    To add rate limiting, you count the # of requests along with keeping track of a timestamp. On each request compare the current # of requests to the # at the last timestamp and see if it's above your limit. If so, deny the request.

     

    Something like this

    //$lastTimestamp = timestamp of last check
    //$lastCount = whatever $count was at last check
    $now = time();
    $count++; 
    $timeDiff = $now - $lastTimestamp;
    if ($timeDiff > 1){ //Ensure timestamps have changed
       $countDiff = $count - $lastCount;
       $lastTimestamp = $now;
       $lastCount = $count;
    
       if ($countDiff/$timeDiff > 5){ //if more than 5 requests per second
          denyRequest();
       }
    }
    

     I see.

     

    And for the denyRequest function just simply return or exit out the user?

     

    And this issue wouldn't be prevalent if I were using a more modern approach, like socket.io/node.js correct?


  7. function wsProcessClientMessage($clientID, $opcode, &$data, $dataLength) {
    global $wsClients;
     
    // check opcodes
    if ($opcode == WS_OPCODE_PING) {
    // received ping message
    return wsSendClientMessage($clientID, WS_OPCODE_PONG, $data);
    }
    elseif ($opcode == WS_OPCODE_PONG) {
    // received pong message (it's valid if the server did not send a ping request for this pong message)
    if ($wsClients[$clientID][4] !== false) {
    $wsClients[$clientID][4] = false;
    }
    }
    elseif ($opcode == WS_OPCODE_CLOSE) {
    // received close message
    if (substr($data, 1, 1) !== false) {
    $array = unpack('na', substr($data, 0, 2));
    $status = $array['a'];
    }
    else {
    $status = false;
    }
     
    if ($wsClients[$clientID][2] == WS_READY_STATE_CLOSING) {
    // the server already sent a close frame to the client, this is the client's close frame reply
    // (no need to send another close frame to the client)
    $wsClients[$clientID][2] = WS_READY_STATE_CLOSED;
    }
    else {
    // the server has not already sent a close frame to the client, send one now
    wsSendClientClose($clientID, WS_STATUS_NORMAL_CLOSE);
    }
     
    wsRemoveClient($clientID);
    }
    elseif ($opcode == WS_OPCODE_TEXT || $opcode == WS_OPCODE_BINARY) {
    // received text or binary message
    if (function_exists('wsOnMessage')) wsOnMessage($clientID, $data, $dataLength, $opcode == WS_OPCODE_BINARY);
    }
    else {
    // unknown opcode
    return false;
    }
     
    return true;
    }
     
     
     

     

    Okay, this is the code that processes the client messages.   It's extracted from here: http://code.google.com/p/phpwebsocket/ and I use it.

     

    My problem is. I call a mysql select on a function via my websockets using this:

     

     

     


    cb.socket.send('LOOTITEM 2213123');

     

     

     

     

    (The CB class just connects it to the socket and sends it off)

     

    But I have a problem.  I can crash my own server, just by going into Google Chromes console tab and spamming this:

     

     


    cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');cb.socket.send('LOOTITEM 2213123');

     

    Then I press enter, and look at my console. And a shit ton of queries are instantly checked and then it pops and says:

     

    33996f94672e498f0fd461dfa63989cb.png

     

    So, this is way bad. Because people can just do this and crash the server. I need to limit the requests to atleast 1 second. Any idea?

     

  8. I already have a web based RPG game I am developing. Here is a small video to showcase the loot animation.

     

     

    My problem is, I want to add combat. I will be using html 5 websockets. I already have a websockets server up so multiplayer isn't the issue.

     

    A good combat system I found is on this game:

    http://treasurearena.clay.io/

     

    I'm not going to dig out the source code, and try to extract the combat system from this game. Just trying to find something similar that I can use, does anyone have any recommendations?

     

    Thanks!

     

    Edit: It can be as simple as swinging a freaking sword and moving. That's all I really want, I just don't want the boring 'click', 'click', and 'click' bullshit.

  9. I'm not sure how you came to this conclusion; from every benchmark I've ever seen, node.js beats PHP in comparable situations. Especially in this kind of scenario. If you've performed any kind of benchmarking (results?) and have seen PHP seem favourable, you should be providing specifics.

     

     

    'Their style' is just the same as any other node application/library. It takes time to adapt to writing the majority of your code asynchronously, in order to get the best out of node. If you've been writing it in a way that goes against its nature, it's not hard to imagine why you're not seeing the performance others are seeing.

     

     

    Well, I am using that php websocket server I linked above and I love it. It's very easy to transfer my existing game code that is written in PHP over to the server that is also written in PHP.  How big is the performance increase from using node.js instead of a php websocket server? Is it noticeable? Is it only worth it, if you're having like a thousand concurrent users connected, etc, etc?

     

    Because I DO not and quite frankly, cant switch to node.js because I am not familiar with javascript as much as I am with PHP. I love php way more and love this php websocket server, but not sure if a php websocket server can be used in production.

  10. Matt is still there actually. And with v4 coming out soon (currently on beta 3), I imagine it has been rewritten.

     

    But I dunno if the phpf team will upgrade ;-) I'm just a lurker again

     

    Yeah, I see Matt on the official forums, but I don't think he writes any code anymore? (Not sure)  I haven't looked at v4 yet, so maybe that will change my mind.  And hopefully.. this bug gets fixed in v4 eh? 

     

    Should I report it on their official forums?

  11. I found this bug when creating my topic here:

     

    http://forums.phpfreaks.com/topic/292939-padding-around-dynamic-generated-rectangles/

     

    I spent 10 minutes writing up my issue after I copy and pasted my code inside the

     brackets. Then, what do you know? I submitted my post with all my writing below my [code] brackets and BOOM it was all gone. Only my code was showing. That's what issued Requinex to reply like that, it's a nasty forum bug.

     

    Here is a video I made to help explain and re-create the issue.  Hopefully you guys fix it, thanks!

     

    https://www.youtube.com/watch?v=LaMXSYkZTfg&feature=youtu.be

  12. Found the solution!

     

    Sorry for the double post, but I cannot edit my post? :P

     

    Anyways:

    for($i = 1; $i <= 30; $i++){
     
    $pos1 = mt_rand(1,30);
    $pos2 = mt_rand(1,30);
     
    echo '<div class="itemLootBox Unique fadeIn" onclick="lootItem(this)" style="left:'.$pos1.'px;top:'.$pos2.'px">Lunar Rock</div>';
     
    }

    I simply added FLOAT:LEFT to my .itemLootBox container in my css! Then gave it a 30 top, and left padding for each float :) Works great now.

  13. Here is my code:

    for($i = 1; $i <= 30; $i++){
     
    $pos1 = mt_rand(1,900);
    $pos2 = mt_rand(1,100);
     
    echo '<div class="itemLootBox Unique fadeIn" onclick="lootItem(this)" style="position:absolute;left:'.$pos1.'px;top:'.$pos2.'px">Lunar Rock</div>';
     
    }

    ffc89e21188adb41666bcf5be405e364.png

     

     

    The dimensions of that container is:

    Width: 980px

    Height: 130px.

     

    These correspond with $pos1 and $pos2 respectively.  I reduced 980 to 900 for the mt_rand because the boxes look weird when they get positioned to the edge. 

     

    And my problem is, the divs are being randomly generated, but sometimes overlap others. Is there a way to add a function / if statement so I can check against $pos1, and $pos2 to add spacing so the boxes will never overlap? (They don't have to never overlap, but some type of padding would be way better).

     

    Edit: Try to think of it as a grid like system, and each rectangle has it's own box of it's 'own' if you will. Wheres there is a padding around each grid. Not sure how to do this

  14.  

    MYSQLI.

     

    But I can grab the unixtimestamp and check it with PHP code though. I'm just using mysql to securely store the last_attack field. 

     

    Wait, would I have to use http://php.net/manual/en/function.microtime.php instead?

     

    Why does the PHP document say microseconds? "microtime() returns the current Unix timestamp with microseconds. This function is only available on operating systems that support the gettimeofday() system call."

     

    Is microseconds the same as milliseconds I assume?

    Edit: Wait, nevermind micro is 1 millionth of a second. I'm herp derping hard.

  15. Since I got my websocket PHP server running nicely with my MYSQL, I can now have some fun :)

     

    Attack speed is very simple, but I need your help with the unixtimestamp.

     

    For example, There is a field name called "last_attack" and each time a user attacks a mob and a skill was performed; it will be updated with:

    time();

    Then I disable the attack button for 2 seconds client side, but I also check that value against time() serverside as well.

     

    Now let's say the user's attack speed is 1.30%

     

    I want to make that Attack Speed check, to check it dynamically.

     

    It should now check only if the attack was less than 1.7 seconds ago instead of 2 seconds. How do I split up the unixtimestamp to work with percents?

  16. You can go Barad's route and craft one up, but if you need a good quick one:

     

    https://github.com/jimmiw/php-time-ago

      0 <-> 29 secs                                                             # => less than a minute
      30 secs <-> 1 min, 29 secs                                                # => 1 minute
      1 min, 30 secs <-> 44 mins, 29 secs                                       # => [2..44] minutes
      44 mins, 30 secs <-> 89 mins, 29 secs                                     # => about 1 hour
      89 mins, 29 secs <-> 23 hrs, 59 mins, 29 secs                             # => about [2..24] hours
      23 hrs, 59 mins, 29 secs <-> 47 hrs, 59 mins, 29 secs                     # => 1 day
      47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs            # => [2..29] days
      29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs   # => about 1 month
      59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec                    # => [2..12] months
      1 yr <-> 2 yrs minus 1 secs                                               # => about 1 year
      2 yrs <-> max time or date                                                # => over [2..X] years
    
    

    Here is a more lightweight and simpler approach:

     

    http://codeforgeek.com/2014/10/time-ago-implementation-php/

  17. So I've been using this websocket: http://code.google.com/p/phpwebsocket/

     

    Love it because I don't know javascript as well as I do PHP. (Absolutely hated learning socket.io and their style of javascript, just gave up on it).

     

    Anyways, I'm using MYSQL with the php socket for the chatroom authentication with my forum. (Sending the cookie values to the socket, to authenticate user). It's working fine and the MYSQL only get's called for each time a user is authenticated (logged into the websocket). The usernames and sessions are actually stored in a Temporary array which is nice. So only on authentication it queries the database for the authentication itself. (Very lightweight and a smart way for a chat system).

     

    My question is, how does this compare to a node.js and socket.io server with a MYSQL plugin, etc? seems like that route would actually be more intensive?

     

    I don't even need to include the socket.io.js for the client / PHP setup I have here as well. This way seems lightweight in my opinion (clientside) but not sure on the server end.

     

    Thoughts? 

     

    TLDR: Running a PHP Websocket as compared to a node.js/socket.io server with mysql plugins the same in performance? Is it even noticeable? Should I be worried?

     

    Edit: Disregard  compatibility issues too.  ( Using this http://tools.ietf.org/html/rfc6455 protocol is fine for my audience and intentions )

  18. Storage space efficiency aside, my first thought would be that each cell is a number 0-15 indicating where there are not walls. A bitmask.

       WSEN
     0 0000
     1 0001
     2 0010
     3 0011
     4 0100
     5 0101
     6 0110
     7 0111
     8 1000
     9 1001
    10 1010
    11 1011
    12 1100
    13 1101
    14 1110
    15 1111
    The cell with the ◄ would be a 12: N=0 (0), E=0 (0), S=1 (2**2=4), W=1 (2**3=8 ). Moving S brings you to a 3 cell (N+E).

     

    In MySQL you can do that with a SET automatically.

     

     

    When you say each cell, you mean each number in the row right?

     

    That makes sense, so I would just need to create a function that checks it serverside to make sure the player can only move away one block at a time? (e.g: No flying or moving from block 1 to 15).  That will be a bit tricky for me, but I understand the process now. Thank you.

     

    This system would also be used as data to be sent from the client to the websocket for a serverside mmorpg I assume.  (For serverside storage of characters positions and whatnot and preventing speed hackers and teleporters). Although, this would be very CPU intensive? Doesn't quite look that bad.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.