Networking in C++ Part #3: MMO Client/Server Framework, Tweaks & Client Validation

แชร์
ฝัง
  • เผยแพร่เมื่อ 23 ธ.ค. 2024

ความคิดเห็น • 178

  • @javidx9
    @javidx9  4 ปีที่แล้ว +54

    Hello! I'd be really interested in seeing your alternatives for uint64_t scramble(uint64_t nInput) as used in the context of the video! TH-cam Comment Coding FTW!

    • @derzweig205
      @derzweig205 4 ปีที่แล้ว +5

      I wouldn't bother because it's just useless work that eats server resources. What you really care about at this point is that both can claim knowledge about the same protocol, just so to have the connection open for a bit longer. So for tat reason a bit of plain text like "olc 1.1" is much better. You can check that its olc and not http or random junk. Furthermore 1.1 can be checked for an existing version etc. Again its just there to establish both speak a common language.
      Once that is done (or not), you can move on to some form of actual encryption / authentication in order to prevent session theft, and or ensure that the user is really the one that it claims to be.

    • @lukeb8349
      @lukeb8349 4 ปีที่แล้ว +12

      I don't see how scramble is a secure method for client validation. Since we're building native code here, can't an attacker just decompile the binaries and figure out what's going on inside this method? If our threat model is that we're assuming a user won't do this, then the safest option might just be to include a server certificate with the game binaries and have the server/client perform public-key cryptography (the server sends a random value, the client encrypts the hash using the public key and well-known secure hashing algorithms, and the server verifies its private key decrypts the hash to the sent value).
      I was taught that when it comes to cryptography, don't ever even attempt to write a secure method. It almost never is cryptographically secure, and we should be using a well-known algorithm that experts design. So in this case I'd argue exposing the method used (or at least not making an effort to obfuscate it) and just hiding the public key is the right move.
      The benefit of this is also that you can rev the sever version just by making a new certificate to include in new releases.

    • @unicycle332
      @unicycle332 4 ปีที่แล้ว +2

      A good alternative would be an HMAC function that uses a secure hash function like HMAC-SHA256 for example.
      An HMAC function takes two arguments "Message" and "Key". In this case you would put random data into "Message" and then use some secret data which could also contain the version number into "Key". You will get an output of a fixed length (256 bits for SHA256).
      You can use it in the same way as your scramble function by computing the HMAC on both the client and the server after sharing the random data and then comparing the results.
      It is extremely difficult to figure out the HMAC key from the message.
      I think this method is better than the current scramble implementation because well known hash functions have been tested and proven to stand up to attack. The current scramble function is what's known as "rolling your own crypto" and is highly disadvised.
      There are still many security issues with this approach and this method cannot be relied upon on it's own. For example an attacker could create lots of connections to use up server CPU resources computing the HMAC and this method doesnt protect the connection of a valid client after the handshake has finished.
      Basically this will still not ensure a secure connection but that's ok for a tutorial.

    • @gideonmaxmerling204
      @gideonmaxmerling204 4 ปีที่แล้ว +2

      well, I wouldn't have that function, any attacker can just "fish" the function out of your binaries, what you should do is make a header validation function, if the header is invalid (length is too long or the message type is outside the bounds) then just throw it out

    • @OneMeanDragon
      @OneMeanDragon 4 ปีที่แล้ว +3

      if you go the way of battlenet-1, theres a few blocks.
      initial single byte = connection type, if that validates, client follows up with a game version check request, which could require another connection to the server (connection type ftp) for a dll to be downloaded to validate the client executable and cdkey if it used one, if you pass that, your to follow up with either account create or account login, if you create you follow up with login, if login passed your effectively on the server, at the server chat level in a channel based on your provided language.
      all their games during that time except 1, used a broken sha1, and the other used srp-3.
      rather simple and effective compaired to what their newer games run on lol.

  • @gamesilo7515
    @gamesilo7515 4 ปีที่แล้ว +40

    I honestly don't know how i discovered this channel now ? How could i miss it this whole time ? This is pure gem. Thank you sir.

    • @javidx9
      @javidx9  4 ปีที่แล้ว +8

      Cheers buddy!

    • @QuickNETTech
      @QuickNETTech 3 ปีที่แล้ว +4

      I found it because of "Forbidden C++", stuck around, watched a lot of the back content and the watched most of what's come after.

  • @wolpumba4099
    @wolpumba4099 4 หลายเดือนก่อน +1

    *Summary*
    This video focuses on addressing two key issues in the framework from Parts 1 & 2: CPU load and client validation.
    *1. Problem: High CPU Usage on Server and Potential Solutions* (0:00)
    * The server example consumes a full CPU core even when idle (demonstrated at 0:58).
    * Client applications also utilize 100% of a CPU core, but this is less of a concern (since games typically demand high processing for logic and rendering). (3:06)
    * *Application-Specific Considerations:* Whether high CPU usage on the server is a problem depends on the type of server-side logic. (2:20)
    * A server primarily focused on relaying messages should be efficient and not constantly consume CPU.
    * A game server running AI or simulations might legitimately need full CPU power.
    * *Solutions:*
    * *This video's focus: Server sleeps until a message arrives.* (4:00)
    * Other potential solution: Utilizing a dedicated server framework (briefly discussed) for applications demanding maximum server performance. (2:54)
    *2. Implementing a Sleep Mechanism for the Server* (4:05)
    * *Threadsafe Queue Enhancements:*
    * `wait()` function added to `net_tsqueue.h`. This function blocks the calling thread until a message is pushed into the queue, thereby releasing the CPU resource until needed. (4:44)
    * Implemented using a `std::condition_variable` to signal when the queue transitions from empty to non-empty. (4:54)
    * A `std::mutex` is used to protect access to the condition variable. (4:58)
    * `notify_one()` is used to signal the condition variable in the queue's `push_back` and `push_front` functions. (6:35, 6:39)
    * *Server (`net_server.h`):*
    * A boolean flag `bWaitforActivity` added to control whether `Server::Update()` utilizes the `queue_incoming_messages.wait()` functionality. Default is set to `false` (7:16) to allow user control.
    *3. Problem: Server Vulnerable to Malicious Clients* (7:58)
    * Demonstration using telnet to send random data (8:31) results in massive memory allocation on the server (a sign of the server misinterpreting the data). (8:34)
    * The server is open to attacks from malicious actors (like port sniffers). (9:09)
    * Compatibility issues might arise when using different versions of the client and server. (9:25)
    *4. Solution: Client Validation* (9:42)
    * The goal is to add a step where the server verifies that the client understands the network protocol and is "friendly". (9:42)
    * A basic "Hello" handshake is considered, but rejected as too easily bypassed. (14:31)
    * *Challenge-Response Validation* (15:04):
    * The server generates random data. (15:37)
    * Server sends the data to the client. (15:40)
    * Server calculates a "scrambled" version of the data using a secret function. (15:42)
    * Client receives the data, performs the *same* scrambling function on it, and sends the result back to the server. (15:51)
    * Server compares the client's result with its own scrambled version. (16:00)
    * If they match, the client is validated as authentic. (16:05)
    *5. Implementation of Validation* (14:31)
    * `Connection` class (`net_connection.h`):
    * A `scramble(uint64_t)` function is added to handle scrambling the data (specific implementation intentionally kept simple in this tutorial, with emphasis on needing a more secure approach). (17:28)
    * Variables added:
    * `nHandshakeOut`: Stores the random data sent by the server.
    * `nHandshakeIn`: Stores the data received from the client.
    * `nHandshakeCheck`: Stores the server's scrambled data.
    * *New Functions:*
    * `WriteValidation()`: Asynchronously writes the `nHandshakeOut` data to the client. (20:52)
    * `ReadValidation(olc::net::Server* pServer)`: Asynchronously reads the response (`nHandshakeIn`) from the client, calls the `scramble()` function as needed, and triggers further actions. (21:36)
    * `Server` Interface (`net_server.h`):
    * Function `OnClientValidated(olc::net::connection& conn)` added (as virtual). Called from `Connection::ReadValidation()` when a client's response passes validation. (23:22, 24:25)
    * Control Flow Changes:
    * `Connection` constructor:
    * If server-owned: Generates random data for `nHandshakeOut`, calculates `nHandshakeCheck` (using `scramble()`). (19:15)
    * `Connection::ConnectToClient()`: Calls `WriteValidation()` to initiate the handshake. (20:35)
    * `Connection::ConnectToServer()`: Calls `ReadValidation()` to start the client-side validation process. (20:21)
    * `Connection::ReadValidation()`:
    * If client-owned: After receiving the challenge, calls `scramble()` on it, assigns the result to `nHandshakeOut` and then calls `WriteValidation()`. (22:36)
    * If server-owned: Compares the received `nHandshakeIn` with `nHandshakeCheck`. If they match, the client is validated and `pServer->OnClientValidated()` is called. Then `ReadHeader()` is triggered to resume normal message handling. (23:03)
    * *If validation fails in either case, the connection is closed immediately.* (24:10)
    *Key Improvements & Takeaways:*
    * *Reduced CPU load:* By using a condition variable and waiting for messages, the server significantly reduces its idle CPU consumption. (7:28)
    * *Basic client validation:* The added handshake process significantly improves server security by preventing most connection attempts by non-conforming clients, including malicious ones.
    * *Modular design:* Validation logic is contained within the framework, making it transparent to users and simplifying client/server application development.
    * *Room for Improvement:* The `scramble()` function's simplicity is highlighted (17:28), stressing that more sophisticated cryptographic techniques are crucial for robust real-world security.
    i used gemini 1.5 pro to summarize the youtube transcript

    • @銅學-k7e
      @銅學-k7e 4 หลายเดือนก่อน

      Thx you bro

  • @robinsonlew4467
    @robinsonlew4467 3 ปีที่แล้ว +8

    Although each video is less than an hour, it makes me half a day to consume it. I'm sure the time you spend on each video must be more than several days. Thank you very much javid!

  • @danbopes6699
    @danbopes6699 4 ปีที่แล้ว +28

    I think it would have been awesome if you mentioned that this handshake is also a good way to prevent against DDoS attacks.
    A lot of server apps now take advantage of cryptographic functions to prevent against DDoS attacks, by having the client do a fairly process intensive task (Like sit in a tight loop, processing hashes), that is extremely simple for the server to validate (Essentially what crypto-chains use).
    ie. Provide the client with an initial seed # (serverSeed) randomly generated, and a complexity #. Next, the client takes the initial seed #, and begins to process thousands of hashes (Which entirely depends on the complexity #):
    The client starts a loop:
    for (var i = 0; i < int32.MaxValue; i++) {
    var result = sha256(initialSeed + "|" + clientInt)
    // Next we look at the number of zeros that the seed starts with
    if (result.substring(0, complexityNumber) == "00000...complexityNumber") {
    //We found a sha seed that starts with the number of 0's required in order to authenticate
    completeHandshake(clientInt); // Pass this clientInt back to the server
    }
    }
    The server then can really simply calculate one SHA256 hash:
    sha256(initialSeed + "|" + clientInt)
    // If the hash generated here, meets the complexity, allow the connection, otherwise simply discard it/block the connection.
    The client then does a tremendous amount of work to connect, thus stopping the server from wasting a ton of resources on processing connections. A quite ingenious way: If the client takes 200ms to generate this seed, for someone to DDoS, 200ms is an absolute nightmare, which will overwhelm their systems before they can do any damage to yours.

  • @Dave_thenerd
    @Dave_thenerd 4 ปีที่แล้ว +7

    5:47 It's worth mentioning that if you're developing for Windows there is a Windows Kernel specific Condition Variable type and Memory Barrier type which in combination both prevent spontaneous wake up and dead lock (in this scenario). std::condition_variable is not 100% guaranteed and std::memory_barrier [in C++ 20] are both generalizations and don't have real kernel-based implantations (Windows and IBM's Zos are the only OSs which have memory barriers in the kernel at the moment) so they will not prevent spontaneous wake up or dead lock 100% of the time but like 90% of the time) An adaptor pattern with Windows specific code would make this a super stable server.

  • @Salehalanazi-7
    @Salehalanazi-7 4 ปีที่แล้ว +88

    Reminder that he has a Patreon

    • @leoreleases
      @leoreleases 4 ปีที่แล้ว

      OLC, make a video showing how do a radial gradient effect in a plane, :D
      It's an almost general effect in games

  • @onogrirwin
    @onogrirwin 2 ปีที่แล้ว +1

    best video on the internet so far this epoch.

  • @contentnation6108
    @contentnation6108 4 ปีที่แล้ว +12

    I think the scambling function as a stub for a connection handhake is fine for a tutorial series. But nothing that should be used in production. You never ever should rely on security by obscurity ("secret code" that is in the client application). Better would be an open protocol with good cryptographic authentication (like per user unique username/password over tls), but this would be too advanced for a tutorial like this. So make a remark, leave it in and go on ;)

  • @VmsCentral
    @VmsCentral 4 ปีที่แล้ว +2

    @javidx9 25:30 forward declaration is unable here according to used method OnClientValidated of server_interface at 23:27 of video.
    Yes, one of project can use only forward declaration but second required including of header with server_interface class.

  • @drew21t
    @drew21t 4 ปีที่แล้ว +1

    Guys you've got to realize that this is a simple approach to client validation and isn't by any means what you should use. He's, like always giving you something you can work with. If you're looking for actual approaches to doing proper client validation, you want to look at implementing a login process using some sort of key system with a database like any other authentication process in application development does.
    Keep in mind that there isn't a single mmo out there that you don't type in some sort of authentication credential into before logging in to the game. His process is just a good starter for you to look at expanding upon. I assume so that he doesn't have to host the infrastructure to do proper authentication etc, which I feel because who wants to host more than they have to.

  • @germandiago2193
    @germandiago2193 4 ปีที่แล้ว +1

    Go ahead javidx9. You are the single best ever person I have seen at explaining non-trivial programming topics.

    • @XYZ-bz8tf
      @XYZ-bz8tf 4 ปีที่แล้ว +1

      Dude..he fundamentally teaches the most important concepts.

  • @douggale5962
    @douggale5962 4 ปีที่แล้ว +7

    I almost suggested using an asymmetric public key algorithm to exchange keys and become immune to man in the middle attacks - then I realised, the attacker has complete control over the client, they can do their hacks before the encryption and defeat that as cheat prevention. Anti-cheat must be done primarily on the server, where attackers have no control over it.

    • @javidx9
      @javidx9  4 ปีที่แล้ว +9

      Correct Doug, the server will need to look for "impossible" situations, such as player movement speeds etc

  • @_syedmx86
    @_syedmx86 4 ปีที่แล้ว +11

    "Bonjour"
    "Yo"
    Very nice

  • @JoshRosario310
    @JoshRosario310 3 ปีที่แล้ว +5

    Epoch caught me off guard 🤘

  • @mohammade.8770
    @mohammade.8770 4 ปีที่แล้ว +8

    The Legend strikes again ♥️♥️♥️

  • @palerider2143
    @palerider2143 หลายเดือนก่อน

    You’re teaching the next generation
    man

  • @billybest5276
    @billybest5276 4 ปีที่แล้ว +5

    From the EPOCH till the break of dawn and so on ...∞

  • @eriktarnok391
    @eriktarnok391 4 ปีที่แล้ว +8

    I am into creating operating systems. Everyone has their own favorite thing.

    • @jphvnet
      @jphvnet 4 ปีที่แล้ว

      Hahaha

    • @mansirrabiu7412
      @mansirrabiu7412 4 ปีที่แล้ว +1

      You must be a genius 👍

    • @eloquentlyemma
      @eloquentlyemma 4 ปีที่แล้ว +1

      I can relate to that:-) May I recommend Fundamentals of Operating Systems by Lister and Eager. I don’t know about later versions but the one we used in College - early 90s as really interesting and taught me so much.

    • @eriktarnok391
      @eriktarnok391 4 ปีที่แล้ว +1

      @@eloquentlyemma
      Thank you very much.

  • @r1pfake521
    @r1pfake521 4 ปีที่แล้ว +1

    Nice to see how validation could be implemented, but honestly I think for this kind of project a simple header validation (check for valid id and a max message size) would be good enough, since the current validation logic can be easily "hacked" anways.
    These simple pre filters (id and size) would already disconnect many random connects and the ones who sent a corret header, but "invalid" data (by accident or purpose) must be filtered out later anyways, because the server has to validate everything the client sends to it. For example if the client sends a "UseItemRequest" message with invalid data (for example an item id that doesn't exist), then the server has to detect the invalid message anyways, no matter if it was sent by a client, random connect or hacker.

  • @sqw33k
    @sqw33k ปีที่แล้ว +1

    6:36 Can someone please explain to me why we are locking using muxBlocking here? Isn't this already locked by the wait() function resulting in a deadlock?

  • @ratchet1freak
    @ratchet1freak 4 ปีที่แล้ว +7

    your condition variable use is wrong,
    no need for the second mutex and the in the wait() the unique_lock (of the original mutex) should be moved to outside the while loop.
    Otherwise if you get preempted right after the empty call and before locking the blocking mutex and another thread does a push you can still be stuck in the wait without getting woken.
    You can also pass a lambda to make the while loop proper: cvBlocking.wait(muxQueue, [&](){return !empty();}); this will handle the loop for you and will wait until the predicate returns true.

    • @PetrPss
      @PetrPss 4 ปีที่แล้ว +2

      Yes! I made comment saying this to previous video month ago. Looks like it got ignored.

  • @zuhail339
    @zuhail339 4 ปีที่แล้ว +2

    My go-to for C++ ♥️

  • @nikkiofthevalley
    @nikkiofthevalley 3 ปีที่แล้ว +1

    I've been having an issue. For some reason, the code in part 2 doesn't work properly. It only lets me send 1 ping message, and it takes a few tries to get it to send anything but garbage data, and the resulting time is something like 2 centuries. I even resorted to copy/pasting code, just to see if I missed something, but no, it still doesn't work properly.
    (The other message types don't work either, it's the same with the ping)

  • @whoisheiforgothisname2103
    @whoisheiforgothisname2103 4 ปีที่แล้ว

    I don't know what your saying but I like your words magic man.

  • @manas_singh
    @manas_singh 4 ปีที่แล้ว +3

    I had been waiting so long

  • @williamokano
    @williamokano 4 ปีที่แล้ว

    You can't imagine how anxious I was waiting for this part 3 😂.
    Waiting for the MMO implementation and furthur tweaks

  • @misterhat5823
    @misterhat5823 4 ปีที่แล้ว +1

    Why not check the size of data before allocating memory? If sent a data size in the header that is bigger than expected, close the connection instead of allocating the memory.

  • @goldenlava1019
    @goldenlava1019 4 ปีที่แล้ว +1

    Soooo we are using TCP sockets, but the goal is to make a game with this. From what I know (I don't know very much) TCP sockets are good for sending chat messages or other messages that you need to get there in the same order, but if I need to send the players position to the server every frame then I don't care if some of them don't get there, the server just needs the current players position. That's what you would use UDP sockets for. So I'm just wondering if we are going to add UDP sockets to the framework, or if we are just going to make a game that doesn't need to send a lot of data to the server every frame.

    • @drew21t
      @drew21t 4 ปีที่แล้ว +3

      The idea is that he established a framework that can use pretty much any type of connection up to the user. So what you want to do is go back to the first video when he was declaring the connection type and create a second one for UDP and then adjust accordingly to support it. And MMO's don't just use UDP they use both a TCP and UDP connection in general. Most of the time you actually have two connections to the game world not just one. UDP is used to send stuff that can get lost like you said, world position, and TCP for really critical things like, for instance, headshots hits or damage calculations that should end processes for other players etc. At that point it really comes down to how your game functions, is it a fast paced FPS then you're probably going to be sending a lot of TCP messages, but for something like chess or a role playing game, you can get away with UDP messages.
      The point is the framework allows for either type to be sent.

  • @АндрейБорисов-и4о
    @АндрейБорисов-и4о 3 ปีที่แล้ว

    Thanks sir Javid! Cool videolesson!

  • @xBZZZZyt
    @xBZZZZyt 3 ปีที่แล้ว +1

    What if client sends garbage after being successfully validated?

  • @ugn_s
    @ugn_s 5 หลายเดือนก่อน

    Hello! Why "OnClientDisconnect" function is not working ?

  • @mad_t
    @mad_t 3 ปีที่แล้ว

    omg you scared the crap out of me with that EPOCH.................. :)

  • @Hawkadium
    @Hawkadium 4 ปีที่แล้ว +7

    "Erroneous WakeUp" also known as the NSA checking in on you.

  • @Froggysrevenge
    @Froggysrevenge 4 ปีที่แล้ว +1

    I'm probably not contributing much, but according to the cryptography class I took in college, a good cryptographic function can be known. Things like RSA are public knowledge, but they're still secure because as long as you don't know what the key is, you can't get in, even if you know how the lock is built. Assuming nobody will reverse engineer your code is security through obscurity, or not secure at all.
    It's probably fine for a game, but with things like passwords and sensitive information, trusting nobody to reverse engineer your stuff isn't smart.

  • @centis4533
    @centis4533 3 ปีที่แล้ว

    Hi, Could you please help me, How to construct a TCP Protocol with 3 arguements? I have the "IP Address", "Port", & "An integer" as third arguement for indentification of the cconnection.

    • @javidx9
      @javidx9  3 ปีที่แล้ว

      The third is a pass by reference argument, ie it will be populated by the function. In the case of asio, it's an error code, so you can examine it to see how the attempt to connect performs.

  • @Ownage4lif31
    @Ownage4lif31 4 ปีที่แล้ว +1

    What about have a user/pass system that connects to a DB. Let's you in if authorized, else kicks you out.
    But I do believe most games usually have a token generated by the lobby/client that is used for the socket to identify the player.
    By no means do I know what I'm talking about. Just a few guesses here and there.

  • @metalhead3ecr
    @metalhead3ecr ปีที่แล้ว

    In the same way you fixed the Server CPU consumption, can we apply that same method to the clients so they don't use a full CPU core?

    • @metalhead3ecr
      @metalhead3ecr ปีที่แล้ว

      nevermind, got it working. Thanks for the great tutorial series!

  • @maksimsivyy5684
    @maksimsivyy5684 4 ปีที่แล้ว

    Hello, great video! Here is my thought => when some thread calls tsqueue::wait, it might be locked forever(rare case, but what if there is empty queue and we want to close our program), so, is it a good idea to add some bool flag to 'wait' loop + one "wakeup" function to tsqueue(which just sets 'stop' bool flag and calls cvar.notify_all to notify and unblock all threads when we don't want to wait anymore)? This approach seems to be "ill-formed", but how can we finish our app properly while some thread is blocked at tsqueue::wait?
    Also, in my code instead of using 'update' mechanism, I use default callback for every incoming message, provided by io_context::strand to execute these callbacks consistently.

  • @traxooza
    @traxooza 4 ปีที่แล้ว

    Hi Javid,
    In the git repository of this project, you were mentionning that there is a memory leak. I can not figure where it is, any ideas ?
    Thanks

  • @mercygotnerfed315
    @mercygotnerfed315 2 ปีที่แล้ว

    Ill you talk about linked-list more in derth ? I just love the way you explain code

  • @sirius-light
    @sirius-light ปีที่แล้ว

    If the library that implements connection class and all logic is shared between server and client that means client will have this library on his hard drive after he download the client, in this case this library can be decompiled and all handshake logic can be easily analysed and used to hack our server, Am I right or no?

  • @FreeDomSy-nk9ue
    @FreeDomSy-nk9ue 4 ปีที่แล้ว +1

    Hey,
    Do you have an idea about how long this series will be? How many parts exactly.
    coincidentally, I am trying to learn client-server communication (using cpr framework and I feel comfortable with it), but your videos keep coming out and they're really interesting, making me ambitious about learning ASIO.

    • @javidx9
      @javidx9  4 ปีที่แล้ว +4

      I suspect (given my schedule) that there will be two more parts showing how the game is implemented using this framework, though the network nitty gritty is done with now.

  • @tmbarral664
    @tmbarral664 3 ปีที่แล้ว

    @javidx9 just a thought: it may be worth to allow the user to provide his own implementation of scramble, don't you think ?

  • @thehambone1454
    @thehambone1454 2 ปีที่แล้ว

    Would it be fairly easy to convert this to UDP? Will there be UDP tutorials in the future? Thanks for making these.

  • @davidecalaminici2937
    @davidecalaminici2937 4 ปีที่แล้ว

    Hello, there's a way to contact you about the convex polygon collision code or for some other informations? Maybe you don't receive comment notifications on old video.

    • @javidx9
      @javidx9  4 ปีที่แล้ว

      Easiest way is via the discord server!

  • @AI-ec2qb
    @AI-ec2qb 4 ปีที่แล้ว

    You are a Top Notch programmer

  • @PolarisMyWay
    @PolarisMyWay 3 ปีที่แล้ว

    Hej, what about adding encryption SSL/TLS?

  • @SchalaArchives2023ish
    @SchalaArchives2023ish 3 ปีที่แล้ว

    Wait, I thought mutexes (mutices?) guard the whole data structure? Like muxQueue would guard not just deqQueue, but also cvBlocking. I've never seen any mutex assigned an association to a variable. I thought it just guarded the whole scope.
    This validation reminds me of the now-very insecure Hotline Connect protocol. It had a header/body system all the same, but upon connecting, the client sends "TRTPHOTL\0\1\0\2" to which the server replies with "TRTP" and a 4 byte error code, usually 0.

  • @traxooza
    @traxooza 4 ปีที่แล้ว

    19:41 you could also use std::radom_device to generate an arbitrarly-long random data for users that would like to rely on longer-sized validations

    • @valuial_
      @valuial_ 4 ปีที่แล้ว

      I don't think "more random" data would improve this validation. Since it is not the data that is the secret - even being able to predict the random data doesn't gain you anything. The "secret" here is the scramble function.
      One might even suggest using ms since EPOCH is a good choice since you guarantee no repeat of the same challenge being sent.

  • @elvrathstat9653
    @elvrathstat9653 4 ปีที่แล้ว

    Hello javidx9 I have a question: On Silicon Valley tv show they make an app where they are able to convert large files into smaller files so that way they have access to accumulate more data. Can we make something like that and if so how would we call it so I could find a course that does that?

    • @javidx9
      @javidx9  4 ปีที่แล้ว

      This is called compression. A good place to start would be Huffman Encoding, and if you really want to study it, you'll need a course on information theory.

  • @billybest5276
    @billybest5276 4 ปีที่แล้ว

    Amazing as always.

  • @MissNorington
    @MissNorington 3 ปีที่แล้ว +1

    'if (m_nOwnerType == owner::server)' code is linked into the client? Make it a template argument so it only gets linked with the server. Clients shouldn't see that code from a debugger.

  • @myroslavaahafonova3875
    @myroslavaahafonova3875 3 ปีที่แล้ว

    Hi!
    Thanks a lot!
    Please tell me can I enter the number of port by myself from a simple string(cin>>port;)?

    • @nikkiofthevalley
      @nikkiofthevalley 3 ปีที่แล้ว

      ??? You enter a port number, an int, not a string..
      Also, I'm guessing English isn't your native language by the really off grammar..

  • @walidjabari4985
    @walidjabari4985 4 ปีที่แล้ว

    what's wrong with basic http authentification or public/private key pair for your use-case ?

    • @VmsCentral
      @VmsCentral 4 ปีที่แล้ว +1

      @Walid Jabari
      At first probably not tutorial friendly approaches.
      Second - may not enough rate for game purpose.

  • @FalcoGer
    @FalcoGer 4 ปีที่แล้ว +1

    your scramble could simply be AES encrypt with a hardcoded key. AES has hardware implementations for 128bit keys on most architectures, so it should be fairly fast, too. and you can be sure that people are not going to find out your key by looking at the traffic in the near future. of course they would find out your key if you post it on github :P
    of course the initial message from the server could very well include the version number, too, even in clear text.
    Of course you could just encrypt the whole session, but if you go that route you might as well do the whole key exchange thing and use tls1.3.
    www.cryptopp.com/wiki/Advanced_Encryption_Standard

  • @mukeshv5522
    @mukeshv5522 4 ปีที่แล้ว

    Your videos are awesome!!!can u make a series on writing Joystick emulators?

  • @xeridea
    @xeridea 3 ปีที่แล้ว

    So, I can just wait for client to validate, then send junk and crash server..... You still should do checks on each requests. Simple things like capping body size to something reasonable. Also, server could send version, as well as challenge upon connection so client can notify user what version is needed.

  • @nazzak2093
    @nazzak2093 3 ปีที่แล้ว

    You scared me with THE EPOCH dude

  • @blumenkohltv1565
    @blumenkohltv1565 4 ปีที่แล้ว

    I don't see how the scramble is more useful then just sending some data and letting the client add some secret to it and then hash it. I mean if the "attacker" actually has a client he can just edit packet sizes after validation. If its just about blocking random attacks anything that isn't just a static response (that then could be part of a list for bruteforcing) should be equal, or am I missing something? I think there is no way to make anything than can be used in public with client packet sizes, but if I understood you correctly you intend not to do that with the mmo :)

  • @KC-vq2ot
    @KC-vq2ot 4 ปีที่แล้ว

    Javid, more of a philosophical question about dependencies
    At what point bringing a new one in can be justified?
    I try avoiding having more dependencies then absolutelly necessary
    In certain places I end up rewriting ton of code from scratch
    If you put it all together, I probably wrote half of Boost by myself
    I am not some fundamentalist who would write his own OS implementation only to have no external dependencies
    If complexity is not really worth it or I need really big chunk of library and it is just dumb to, basically, remake an existing lib, why would I do that?
    Also, for some dummy functionality where I need working it now and either don't really care about how or replace it soon enough
    What bugs the hell out of me
    Is people adding a new dependency only to use a couple of semi-trivial features that would take only a couple hours or a day to reimplement from scratch.
    Langs like Python are the biggest offenders as dependencies have their own dependancies and you might end up installing Anaconda to read excel data
    Not to mention that some libs (even widely accepted) are badly designed, poorly maintained, rely on some guy in a middle of Siberia not dying during bear hunt or all of the above and you just add a ticking time bomb to the project.
    What is your take on that? I know that you use a lot of external libs in your tutorials, but they are home projects that are not meant to take a lot of time, be simple and you don't really care about lib existing because your interest clearly won't outlast the lib. Even I don't write my own code for that, unless there are some bad offenders like string.h C library (I rewrote a lot of C standard library because it is clearly a product of it's time) or libPNG

  • @kane1356
    @kane1356 4 ปีที่แล้ว

    Thanks handsome bearded C++ wizard!

  • @videobros6556
    @videobros6556 4 ปีที่แล้ว

    Love your videos keep it up!

  • @zergon321
    @zergon321 4 ปีที่แล้ว +1

    What do you think of Go programming language?

    • @javidx9
      @javidx9  4 ปีที่แล้ว +2

      I have no opinion of it.

  • @erikpavlusik6214
    @erikpavlusik6214 4 ปีที่แล้ว +2

    Thank you

  • @kevinkouketsu3952
    @kevinkouketsu3952 3 ปีที่แล้ว +1

    Can you provide the source code? It's been two months since this video. Thanks.
    Amazing serie! Please, continue doing this amazing job.

  • @alecs2056
    @alecs2056 4 ปีที่แล้ว

    Whats stopping me to just decompile the client and extract the function that does the scrumble? I don't need to understand the function I cant treat it an a blackbox

    • @javidx9
      @javidx9  4 ปีที่แล้ว +9

      Nothing at all. In principle you would need to move to secure communications protocols to have anything realistically capable of preventing all attacks. My approach is more of a nuisance prevention.

  •  3 ปีที่แล้ว +1

    You adressed one problem by solving a completely different problem...
    While authenticate the client is an important problem to solve, it does nothing to actually solve the problem that the consistency of the message header is not protected. The header should include some sort of redundancy field, like a checksum or a crc that guarantee that the header is consistant before trying to use any information from it.
    Also the read message function need to put a reasonable max size on the length, a full 32-bit length field implies you could be trying to read 4 GB from the client, wich doesn't seem necessary.

  • @dempa3
    @dempa3 4 ปีที่แล้ว +1

    I'd be really interested in more videos on proceduraly generated content and especially on how to "save" the users interactions with the proceduraly generated content. And to go even further it would be very interesting to know if one could proceduraly generate agents, besides the user, who interact with each other and the rest of the content independently of the user, as well as with the user.

  • @misterhat5823
    @misterhat5823 4 ปีที่แล้ว +1

    For the scramble data function: Take the sent data and append some known string (possibly the version number) and compute a hash (such as MD5.) Even though MD5 isn't considered secure anymore, I suspect it good enough. If not, there's other hashing functions. For added fun scramble the string before hashing it.

  • @blumenkohltv1565
    @blumenkohltv1565 4 ปีที่แล้ว

    So hyped ^.^

  • @danbopes6699
    @danbopes6699 4 ปีที่แล้ว +2

    I really disagree with your plan to "accept something I'd expect" when you connect. It's quite easy to mimic that by looking at how the client connects, and then specify the max size for integer, to allocate a large amount of memory, and crash your program.
    It would have been lightyears simpler to limit the size that can be allocated to a reasonable size. Anything over that, simply reject and disconnect the client.

    • @javidx9
      @javidx9  4 ปีที่แล้ว +2

      It wouldnt crash anything - the server only reads first 8 bytes of validation. If its incorrect everything else is shut down. I also describe exactly what you argue in the video - about using predefined structures, and just a structure ID to discriminate - and go on to say this is how it will be implemented after we have finished the development of the game, as at this stage the flexibility is more useful than the constraint while developing.

    • @danbopes6699
      @danbopes6699 4 ปีที่แล้ว +3

      @@javidx9 Yes: So your server reads first 8 bytes of validation. A hacker modifies the client, and reads how you connect to the client. (Even complex code, such as WoW and many other MMORPG's, with the use of Ghidra or other decompiler software, can figure out how the handshake is done). Once the handshake is done: The hacked client can then go on to request insane amounts of memory, in a tight loop, to fill your entire process. Predefined structures (With limits in place) would help, but in this instance, setting a simple lower memory limit (Maybe like 1mb for a packet, or 65k) would have been a better solution.

  • @mr.awesome5109
    @mr.awesome5109 4 ปีที่แล้ว +1

    When do you think the series will be finished? Like what number in the series? Just curious.

  • @mursitkc5328
    @mursitkc5328 4 ปีที่แล้ว

    Source?

  • @davidreynolds9649
    @davidreynolds9649 3 ปีที่แล้ว

    Could this be the basis for a real online MMO of thousands (10-25k) of players each making thousands of requests?
    I guess I'm asking if it is scalable or is it best to start elsewhere!

  • @clumbo1567
    @clumbo1567 4 ปีที่แล้ว

    Some DTLS encryption would be good

  • @homomorphic
    @homomorphic 4 ปีที่แล้ว +3

    18:01 the client for a game is under complete control of the attacker, they will simply decompile your client with ghidra and see exactly what the algorithm does.

    • @drew21t
      @drew21t 4 ปีที่แล้ว

      which is why you would actually implement a database auth system where you actually use keys for authentication, but for a simple application framework this gives you something to build upon and ultimately augment.

    • @homomorphic
      @homomorphic 4 ปีที่แล้ว +1

      @@drew21t how do keys help? You're trying to authenticate the client. If you put a private key in the client the attacker has it and can lift the key and use it in their own client.

    • @drew21t
      @drew21t 4 ปีที่แล้ว

      @@homomorphic you do it as apart of the authentication process like you would for any other application. and you do it in combination with some sort of login credential. or you don't use a key at all and just use login credentials like most games do. the point is there are many approaches to authentication that are considered industry standards for proper access.

    • @drew21t
      @drew21t 4 ปีที่แล้ว

      @@homomorphic and, if you do use a key, each key would be coupled with a login credential to ensure that is the user. thats just one way to go about it. basically a password.

    • @homomorphic
      @homomorphic 4 ปีที่แล้ว +3

      @@drew21t this has nothing to do with user authentication. You are trying to authenticate that it is your code that is talking to your server. The attacker (a cheater in a game) is almost always in possession of valid user credentials.
      The only way you can accomplish authentication of the client code, is if you can guarantee that the the client code can be neither tampered with, nor observed, and that is a non trivial problem.

  • @NinjaNJH
    @NinjaNJH 4 ปีที่แล้ว +2

    Nobody:
    olc : DEADBEEFC0DECAFE

  • @danny-jo1rb
    @danny-jo1rb 2 ปีที่แล้ว

    the E P O C H

  • @内田ガネーシュ
    @内田ガネーシュ 4 ปีที่แล้ว +1

    17:44 what is this new English word? is it xor?

  • @MassiveBreaker
    @MassiveBreaker 4 ปีที่แล้ว +1

    EPOCH

  • @markiel55
    @markiel55 3 ปีที่แล้ว

    "Epoch" 19:39

  • @catapillie
    @catapillie 3 ปีที่แล้ว

    french be like
    - bonjour.
    - yo

  • @Голубь-з5ь
    @Голубь-з5ь 3 ปีที่แล้ว

    You know game Dwarf Fortress?
    Could you please explain how dwarvies AI works in game Dwarf Fortress? From proger view ofcourse.

  • @eriktarnok391
    @eriktarnok391 4 ปีที่แล้ว

    Its cool! 😎

  • @delqyrus2619
    @delqyrus2619 4 ปีที่แล้ว +1

    I wish you would take care about stuff like "hole punching"(STUN, etc.). Having a server, that handles every single player, might be very expensive for tiny projects. Having some server-independent communication between clients might be helpful, so you server only needs to tell the clients, where to send their packets. Also it might reduce the delay between actions.

    • @eidodk
      @eidodk 4 ปีที่แล้ว +3

      That would expose the clients to eachother. That's not really an option. If you want to make a "secure" game, you have to control the communication, which you can't if you bypass the server validation and anonymisation of the messages. Also - using UDP to communicate is bad, since there's zero data control.

    • @delqyrus2619
      @delqyrus2619 4 ปีที่แล้ว

      @@eidodk nah, you give them your ip - that isn't something really unusual - actualy every ip in the world is somehow public. Security isn't made by obscurity - it is made by the system.
      of course, you may not want people to know you ip. but you usually don't play with strangers - and in the most tasks, you somehow expose your ip to your friends.(webrtc, which most of the usual communication systems use, does actually the same thing.)
      Of course - if you create some sort of mmo, this is an issue. But there you have much more interesting issues to call, than the protection of the client ip. In these cases there actually is no way around of a central server.

    • @eidodk
      @eidodk 4 ปีที่แล้ว +1

      @@delqyrus2619 I don't know ANY network game, that exposes the players IP's, it would be REALLY unusual, and would expose any player to DDOS attacks.

    • @r1pfake521
      @r1pfake521 4 ปีที่แล้ว

      I also don't know any network game that exposes the player IPs to other players, in the EU you already have to be careful to not even log player IPs on the server, they would crush you if you sent the IPs to other players lol

    • @delqyrus2619
      @delqyrus2619 4 ปีที่แล้ว

      @@r1pfake521 Okay, take any game, that doesn't work with a central server. Like Stardew Valley, Don't Starve Together and so on.

  • @gokusaiyan1128
    @gokusaiyan1128 3 ปีที่แล้ว

    Hey do you mind if I create a blog series based on your videos ( basically referencing it and then making my own ) ?

  • @wjrasmussen666
    @wjrasmussen666 4 ปีที่แล้ว

    Nice.

  • @streetfashiontv9149
    @streetfashiontv9149 4 ปีที่แล้ว

    Hi Javid, i love your videos bro they help me alot especially the ones about gaming. Its slightly off subject but i am trying to make a card game with an image array that holds the cards. I am stuck on this. Do you know how to create an image array in Java that iterates through images in a file?
    cheers

    • @tz4601
      @tz4601 3 ปีที่แล้ว

      What you would rather want is a Card data type. This custom data type would hold information such as suit and value. Separately, you would want to have some sort of data structure to hold resources -- in this case, pictures representing your cards. Each of your cards could then have a pointer to whichever image represents it. One of the big sticking points for me when I was starting to learn programming was understanding that I needed to think about data separate from display. Logic deals with data. When we need to display something, we write some system that matches up data with its appropriate visual representation (whether that's a simple image or a full 3D game renderer). This is a split you'll see all throughout programming; for instance, in the web space we have the pattern Model View Controller.
      As to loading the images, I don't know what libraries to use specifically in Java, but what you would want is to store one image per file. Then you would use an appropriate Java library to load each image one at a time into a resources structure (which could just be an array). In general, code is not smart enough to be able to look at a file containing lots of images and just somehow know how to split them up into their individual component images. 2D games use something called sprite sheets, so if you are able to find a Java game programming library you could look into those as well. Sprite sheets contain lots of images in one file, but they are placed in a precise rectangular grid so the code knows how to split them up.

  • @thatsnuts8935
    @thatsnuts8935 4 ปีที่แล้ว

    nothing just wanna refresh the scrap book

  • @tautvydassiuksta7698
    @tautvydassiuksta7698 4 ปีที่แล้ว

    Make c++ tutorials

  • @GoodWill-s8j
    @GoodWill-s8j 5 หลายเดือนก่อน

    Ok now back to the serious work! Let's rewrite everything without the stupid ASIO.

  • @eriktarnok391
    @eriktarnok391 4 ปีที่แล้ว

    👋

  • @monomere
    @monomere 4 ปีที่แล้ว

    :D

  • @adityadey9591
    @adityadey9591 4 ปีที่แล้ว

    Please sir make a full tutorial on c++

  • @Digidan5
    @Digidan5 4 ปีที่แล้ว +3

    first

    • @Digidan5
      @Digidan5 4 ปีที่แล้ว +1

      turns out this was a lie lol

    • @javidx9
      @javidx9  4 ปีที่แล้ว +3

      smh...

  • @ayush.kumar.13907
    @ayush.kumar.13907 3 ปีที่แล้ว

    EPOCH