- Viewing Profile: Reputation: hplus0603
Community Stats
- Group Moderators
- Active Posts 10,405
- Profile Views 12,702
- Member Title Moderator - Multiplayer and Network Programming
- Age Age Unknown
- Birthday Birthday Unknown
-
Gender
Male
-
Location
Redwood City, CA
#5050803 C++ and MySQL for the server
Posted by hplus0603
on 07 April 2013 - 01:51 AM
In very brief, to create a server, you can start as such:
1) Call socket() to create a TCP socket.
2) Call bind() to bind the socket to your given port, and IP address 0.0.0.0 (IPADDR_ANY).
3) Call listen() for basically historical reasons.
4) Now, enter a loop that does the following:
4.1) Put all active sockets in an FD_SET.
4.2) Call select() with that FD_SET to test readability of sockets. Perhaps use a timeout so you can run periodic events even if the server is idle.
4.3) For the listening socket, if it returns readable, it means someone is connecting; call accept() on it and allocate a data structure with incoming buffer and client information. (This is empty for now.) Put the mapping from socket ID to buffer/client information into a hash table.
4.4) For each connected socket that is readable by select(), call recv() once to attempt to fill up the incoming data buffer in the per-socket data structure. Recv() will not block the first time you call it after select() says it is readable.
4.4.1) Decode, remove, and dispatch any complete packet(s) that are in the receive buffer for this socket/client.
4.4.2) If recv() returns 0, or the client sends a "quit/disconnect" command, or the client is sending bad packets, close the socket, and de-allocate the buffer/client information structure for this socket.
4.5) Goto 4.1
That's really all there is to the basic server loop, based on select(). This will easily get you to many hundred simultaneous users.
#5049636 C++ and MySQL for the server
Posted by hplus0603
on 03 April 2013 - 11:50 AM
Separately, for a real-time game, most developers end up reading the important data into RAM in a persistent process in the application server (call it "game server") and only write back to the database on occasional snapshots or specific events. This is usually done for efficiency purposes.
#5049255 Game Server security
Posted by hplus0603
on 02 April 2013 - 12:13 PM
I would argue that clients are authoritative over the mouse position/movement, and mouse movement translates into camera/aim orientation (assuming FPS-style controls) and thus the client is authoritative for aim. While this makes aimbots easier to write, it's a necessary trade-off (and even without it, aimbots are entirely possible.)You can of course also extend this to numeric values that change over time within the payload of the packet. But in general, I'd say that the client shouldn't be authoritative for any continuous values...
#5049060 Game Server security
Posted by hplus0603
on 01 April 2013 - 08:36 PM
Yes. As soon as something is not right, close the connection. Also, log this to some counter, perhaps correlated with client version reported on connection, so that you can tell if you have a bug that causes users to get disconnected because the client sends bad data :-)Should I catch this case and just close the connection?
Also, put a stringent max size on EVERYTHING. A maximum size on the message type. A maximum size on files downloaded or uploaded. A maximum size on strings. A maximum item count in arrays. And make those limits be fairly limited. This will avoid someone doing things like sending a "valid" packet that claims to have 2,000,000,000 items in it, and thus tying up your sever just receiving and dealing with that packet.
Another popular attack is sending malformed inner data. Say you have a "login" packet that looks something like: name:string, password:string, clientversion:varint.
Now, if strings are zero terminated, then someone can send a valid outer packet (type: login, length: whatever) but then not include a zero byte in the payload. Your decoding function may at that point run past the end of the packet, and read random memory. Don't do that! (Better is to length-prefix strings, and automatically cut them off at 255 bytes max.)
Even if you fix the string, someone might send a badly encoded varint. For example, let's say that varints are encoded with the high bit set when there's a continuation byte, and the high bit clear for the last byte; each lower 7 bits are data, little-endian. For example, the value 0xAA55 would be sent as:
(0xAA55 & 0x7f) | 0x80, ((0xAA55 >> 7) & 0x7f) | 0x80, ((0xAA55 >> 14) & 0x7f)
Now, someone could send a packet that contains the value 0x80 over and over again, causing your decoding logic to never break out of the varint decoding loop. Always establish a maximum length for a varint, or any data type, on the wire.
Once you have the serialization/de-serialization dealt with, the semantics of the packets matter. Don't treat something as "known good." For example, if an entity ID is in the packet, look up that entity ID in a hash table each time you see it. If it's not there, disconnect the player. If a property ID is in the packet, make sure it's valid, and if it's not, disconnect the player. If a floating point value is in the packet, make sure it's not NaN or Inf or denormal -- if it is, disconnect the player.
#5047709 [career] Mobile game server side question.
Posted by hplus0603
on 28 March 2013 - 11:54 AM
If you can make a game that works under those conditions, you'll be well prepared.
Are you going to be the only one working on mobile services back-end, or will you join a team that's already doing it? If you're joining a team, you're likely to be able to learn from the others on the team. Don't be afraid of asking questions until you understand, because that's much better for the team than working on something you don't understand!
#5047091 Client - non dedicated server architecture
Posted by hplus0603
on 26 March 2013 - 07:29 PM
The main problem you'll need to solve is "how do players who want to join, find a server to join?"
One option is a central matchmaker server, but you could just tell people to do port forwarding, and post their server IP/port on an internet forum, and that might work just fine for your game.
#5047090 .Net server and chat channels
Posted by hplus0603
on 26 March 2013 - 07:28 PM
Thus, the data could be:
[0x1, 0x5, "Hello"]
This would say "message type 1 (text chat) on channel 5, data "Hello".
The code for receiving command type 1 would then dispatch to the right channel:
Dictionary<byte, Channel> channels = new Dictionary<int, Channel>();
void DispatchChat(byte[] data) {
Channel chan;
if (!channels.TryGetValue(data[1], out chan)) {
// no such channel
return;
}
chan.ChatMessage(data);
}
There are many other ways of slicing this (such as dispatching on channel first, command second, or using a different container, or targeting messages at "objects" where one kind of "object" is a "channel" or ...)Also: One thread per user works for small numbers of users (a few hundred, say.) For good performance and resource utilization, though, you want to use BeginReceive()/BeginSend() or ReceiveAsync()/SendAsync() and let the OS do the thread pooling for you.
#5044650 Unity Caching in Web Player, without WWW
Posted by hplus0603
on 19 March 2013 - 01:27 PM
There is a WWW interface that allows you to issue a "GET" or "POST" but it's not quite to the level that you can trust a "streaming game experience" to it.
Again, this was about two years ago, so things may have changed since then. We ended up developing our platform on HTML5 + WebGL instead.
#5044317 Client hosted game that seems lik an MMO
Posted by hplus0603
on 18 March 2013 - 01:01 PM
A determined cheater will just run more than one machine, and find one of them hosting some instance that one of his players is in, and then proceed to cheat from there.For the cheating isse - who says a player who is the host has to be running the simulation for the zone they are in ?
#5042467 Multiple Sockets Per Client
Posted by hplus0603
on 12 March 2013 - 03:56 PM
A connection is identified by a four-tuple of (remote IP, remote port, local IP, local port) which means that you can have up to 65535 connections in parallel from one machine to a specific service on another machine. That seems like it should be enough, although remember that TCP connections stay in TIME_WAIT state after being closed for a few minutes, and there actually exists cases where you'll run out! This is mostly for short-lived HTTP requests for service-oriented architecture type systems.
You *can* use a long-lived TCP connection for some messages, and a UDP connection you manage yourself for some other messages. It can work. But, if you're building the UDP part, you might as well put a simple reliability layer on top of that, as long as you don't use that for things like bulk download of large asset files, patches, etc. That will likely actually simplify the messaging/communications code.
#5040086 Smoothing Out Real-Time Movement
Posted by hplus0603
on 06 March 2013 - 01:10 PM
The main problem is that player/player interactions (a k a "collisions") suffers from latency.
The solutions suggested included:
- make the forward extrapolation of player data use a driving AI to get better projected trajectories than plain extrapolation
- have each player detect collisions locally, and if detected, let everyone know that "this player is crashing" -- that may not affect any other player (this is limited client-authoritative simulation)
- make collisions quite violent so that a "correction" camera snap isn't noticeable
- when in doubt, Just Add Smoke !
#5038910 How do I update text (or anything) in a game, in real time?
Posted by hplus0603
on 03 March 2013 - 08:28 PM
If the requirement is "has to be implemented within Game Maker" then that may be a pretty harsh requirement.Hopefully I can pull this off with Game Maker somehow.
I agree with others: Spin up a web server that serves the "news and information" page. Web servers are great at distributing semi-static content. Load this from the game and display it. If you don't need the full HTML DOM / CSS / JavaScript engine, you could probably write a simple text-and-image renderer that understood just enough HTML to display your news blurb correctly.
Most web browsers pay attention to cache control headers, so you can mark your news data to expire a few hours from when it's fetched. That way, a client will re-load news only if it's been several hours since it last saw it.
#5038905 Idea for online multiplayer turn-based game with UDP
Posted by hplus0603
on 03 March 2013 - 08:21 PM
Single-core processes routinely deal with >100,000 connections over TCP these days. As long as you use efficient I/O -- libevent, boost::asio, or similar (or go direct to /dev/poll, I/O completion ports, or whatever your platform provides) you won't see a performance problem from TCP over UDP.each server could stands a limit of CCU by using TCP
TCP consumes more resources when closing and re-connecting, that it does just staying connected but idle. Disconnecting and re-connecting a client while waiting for a move would be very inefficient.
Honestly, it sounds to me as if you're trying to optimize the wrong thing here. How many users do you expect to have playing at the same time? And how much are you able to pay to support that many users? The Amazon Free Usage Tier (a Micro ECC instance, free, for a year, and 20 GB of data transfer per month) can support >1,000 simultaneous online users of a turn-based game using TCP with no problems.
Also, you seem to be assuming things about TCP vs UDP that I'm not sure are true. UDP is not magically "cheaper" in any sense -- it just moves a lot of the management responsibility for connections onto your application, instead of using something ready-made in the kernel. It's still more or less the same work and same memory usage needed. The only gain of UDP is that, if there is packet loss, you don't have to wait for a re-transmit of older data before getting newer data delievered, so if sooner is more important than in-order (such as for VoIP, FPS games, etc,) then UDP may provide a better experience to the player.
#5038500 Java UDP Multicast problems with sending data
Posted by hplus0603
on 02 March 2013 - 01:36 PM
When multiple processes use the same port number on the same host, then only one of them will get any particular incoming datagram. This may be great for scaling a single-threaded program across many cores (fork many processes and have them all bind to the same port) but it's certainly not good for your client/server game situation.The server and client run on the same IP and same port, but I'm sure that is not the problem
The client should not have to bind to any particular port number. Just let the UDP implementation assign a port number the first time you call sendto().
#5038496 RPG-like serverside spell/skill system
Posted by hplus0603
on 02 March 2013 - 01:30 PM
While a plan certainly helps, there's a danger of going into analysis paralysis.Plan your Systems first
I think the most important part is to understand that re-factoring code is a natural part of the evolution of a system. Thus, you should make your overall code as easy to refactor as possible. This may mean using interfaces between each subsystem, so that each subsystem is less dependent on everything else. This may mean using consistent code formatting and naming conventions, so that search-replace and code movement is less prone to typos. And it very likely means writing good automated tests for each piece of functionality you develop, so you know that a re-factor doesn't break the functionality!
- Home
- » Viewing Profile: Reputation: hplus0603

Find content