|
From: Steve J. <ste...@ya...> - 2004-01-10 01:53:59
|
--- Ludwig Nussel <l-...@us...> wrote: > Steve Jankowski wrote: > > --- Ludwig Nussel <l-...@us...> wrote: > > > Steve Jankowski wrote: > > > > But first, I'm not convinced the world needs another game query > > > > protocol. If you implement something for BZFlag that's compatible > > > > with an existing game (HL or Quake), then other game browsers can > > > > support it straight away. That's good for BZFlag, right? > > > > > > Those protocols are flawed in one way or another. AFAIK HL does not > > > deal with fragmented packets and Quake(3) only has a fixed set of > > > player properties. The gamespy format is some kind of standard, but > > > we know it's not easy to deal with either. > > > > Sure they're flawed, but do we need a perfect protocol just to support > > BZFlag? HL does support fragmented packets (some CS servers have entire > > packets full of server rules). > > It's not just for BZFlag, I hope to get this protocol into more > games so it has to be fairly generic. AFAICS HL too doesn't support > arbitrary player properties and transmits the time played a float. > (the code dealing with this in qstat breaks the strict aliasing > optimization of gcc3 btw.) Yeah, you're right about HL being lame about the player info. I was annoyed at HL using a float for connect time, so my solution isn't pretty. > > Multiple outstanding requests. Given that a packet write is a non- > > blocking operation, and a game server is likely to prioritize status > > responses below actual game processing, the server could be sending > > status responses to multiple destinations at the same time. It seems > > like your API can support this, but it requires the app to track the > > state information. If the app can only send 2 of 4 fragments, then it > > has to save the IP, port, queryresponse, fragnr, and reslen in some > > list. The app will then need some code to occasionally run the list > > to try sending more query responses. Seems like the API should take > > care of all these details. > > Isn't that's too complicated? Storing all that information probably > costs more CPU cycles than just calling a couple of send(). I didn't > want to deal with IP Adresses, otherwise it would be necessary to > support IPv4 and IPv6. Supporting IPv6 is not required (and why would you? there's no IPv6 games and game developers are not talking about it). A good API implements all the complicated stuff so the app doesn't have to. If the API is too "thin", that presents a barrier to adoption. That complication has to be some where. If it's in the API, then every app benefits. If it's in the app, then every app gets to make the same mistakes. > > > > I'm concerned about using \n since it might appear in a string (rule > > > value). > > > > I suggest using \0 since that's not a legal character. > > > > > > Strings are always null terminated. \n is used to let the parser > > > know when the e.g. the rules section ends and the team section > > > starts. Like: > > > > > > ... 'r' 'u' 'l' 'e' '\0' 'v' 'a' 'l' 'u' 'e' \0' '\n' ... > > > > Ok, what if a rule name starts with a \n ? Seems unlikely, but > > if you're going to make the perfect protocol, might as well avoid > > all ambiguity. > > Right. That means if \0 is also used as delimiter between rules, > teams and players, a packet would look like > > 'r' 'u' 'l' 'e' '\0' 'v' 'a' 'l' 'u' 'e' \0' '\0' 'p' 'l' 'a' ... > > So an empty string when e.g. a rule name is expected means switching > to player parsing. If no rules, players and teams are to be sent the > packet would be just '\0' '\0' '\0' That's right. > > Why doesn't the API know how big the fragments are? Just supply a 1400 > > byte fragment and the app will either write the whole thing or it won't. > > I don't think a UDP write can ever partially fail. It will either > > write the whole packet, or fail because the kernel packet or socket buffer > > is full. If apps want to tune the packet size, give them a single > > config parameter: qs_set_response_fragment_size( int n_bytes) > > Hmm, I'm still not convinced that the API needs to know the MTU > beforehand. qs_respond_to_query() returns a single string and the > game can call send() with whatever size it likes. If that size is > smaller than the string it just has to call qs_fragment_response() > until nothing is left. qs_fragment_response() updates the header and > does memmove() on the data. Ah, I didn't understand the API. If the app decides to send less than the header size, then the API will break. I think you give up too much control if you let the app chose the packet size. I would avoid memmove() if possible. It's inefficient. Game programmers will appreciate an efficient API. > > > > > I chose 1400 to avoid exceeding the MTU (usually 1500 on ethernet, but > > > > occasionally smaller). > > > > > > If you want to make sure the packet can be tansmitted over the > > > internet you would need to restrict the packet size to 576 bytes. > > > That's the minimum size each device needs to be able to handle. > > > > I'm really only worried about ethernet. MTUs in the 500 range are > > really only used by analog modems. And no one is going to run a > > server behind a modem. > > What about clients? I suppose if you send a 1400 byte packet to an > IP behind a modem the packet gets dropped at the dialup router? Yeah, that's something that never made sense. People say that small MTUs may be used on the internet, but then lots of apps (streaming media, games) run across modems just fine. I don't think they're all doing an MTU negotiation. I'd check my networking book, but it's walked away. Steve |