Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2002:
[Freeciv-Dev] (PR#2316) Reduce bandwith take 3
Home

[Freeciv-Dev] (PR#2316) Reduce bandwith take 3

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2316) Reduce bandwith take 3
From: "Raimar Falke via RT" <rt@xxxxxxxxxxxxxx>
Date: Tue, 12 Nov 2002 10:53:06 -0800
Reply-to: rt@xxxxxxxxxxxxxx


The attached patch is a more or less rewrite of the freeciv network
protocol. The protocol can be broken down into 3 layers:
 - layer 1: defines how the data of each packet is transfered (how a
 packet is serialized)
 - layer 2: defines how packets are transfered (16bit size, 8bit type)
 - layer 3: defines which packets are available to the user (PACKET_*
 and struct packet_*)

Layer 1 is changed to use deltas. Info packets which doesn't provide
new information are discarded. Fields which have the value 0 aren't
transfered.

Layer 2 isn't changed. However there are 4 bits (we only need 12bit
for the MAX_LEN_PACKET out of the 16 available) free per packet. These
may allow specifying the number of bits of a packet. Or maybe there is
another use.

Layer 3 is changed in such a way that PACKET_foo and struct packet_foo
are now tightly coupled. I.e. for each PACKET_foo there is a struct
packet_foo and vice versa. This gives us a function like interface
(the function is executed at the other side). To emphasize this and to
make programming easier direct sends and direct calls are
added. Direct sends means that in addition to the regular send_*
function:

  int send_packet_new_year(struct connection *pc, const struct packet_new_year 
*packet);

there is also a dsend_* function which takes all fields of the struct
packet_* as parameter

  int dsend_packet_new_year(struct connection *pc, int year, int turn);

The implementation is easy:

  int dsend_packet_new_year(struct connection *pc, int year, int turn)
  {
    struct packet_new_year packet, *real_packet = &packet;

    real_packet->year = year;
    real_packet->turn = turn;

    return send_packet_new_year(pc, real_packet);
  }

and is generated. This give such nice results:

 void request_unit_airlift(struct unit *punit, struct city *pcity)
 {
-  struct packet_unit_request p;
-  p.unit_id = punit->id;
-  p.x = pcity->x;
-  p.y = pcity->y;
-  send_packet_unit_request(&aconnection, &p, PACKET_UNIT_AIRLIFT);
+  dsend_packet_unit_airlift(&aconnection, punit->id, pcity->id);
 }

Direct handle means that the handle functions are called with the
fields as arguments. While this doesn't cause a reduction of the code
size it emphasis the function interface and uncouples the handle
function from the packet. Example:

-void handle_new_year(struct packet_new_year *ppacket)
+void handle_new_year(int year, int turn)
 {
-  game.year = ppacket->year;
+  game.year = year;

These direct functions are generated for all packets which have 5 or
fewer fields but not for ruleset packets.

The config file also contains information in which direction packets
are send. This is used for example to only generate lsend_* functions
for packets which are send from the server to the client. Here are
also dlsend_* functions available.

Another major change of the layer 3 was to streamline the parameter to
the remote-functions (i.e. the fields of the packet
structs). Interresting cases are for example:
 - to request the attribute block you have to send a full
 packet_player_request (6bytes). But this isn't needed because an
 empty packet is enough.

 - every unit request has a string (for the naming of a new city)
 which when not cleared takes up bandwidth but is discarded at the
 server

Also the width of the transfered value of different types were
unified. So is a connection id transfered as a 32bit value and as a
8bit value in the current implementation. With the system you can
define all types you want at the top of the file and use these
later. Now the following types are defined (and used):

type COORD              = UINT8
type PLAYER             = UINT8
type CITY               = UINT16
type YEAR               = SINT16
type UNIT               = UINT16
type HP                 = UINT8
type PERCENT            = UINT8
type TECH               = UINT8
type UNIT_TYPE          = uint8(Unit_Type_id)
type GOLD               = UINT32
type CLAUSE             = uint8(enum clause_type)
type EVENT              = uint16(enum event_type)
type TERRAIN            = uint8(enum tile_terrain_type)
type SPECIAL            = uint16(enum tile_special_type)
type NATION             = uint16(Nation_Type_id)
type GOVERNMENT         = UINT8
type CONNECTION         = UINT8

I also made some real changes. So did the old code for example tries
to move a unit into the city if the clients requested the establishing
of a trade route. This can be done by the client and is removed.

The format of the various includes aren't the best. And it is also not
the final version.

This patch isn't intended to be applied but serve as a discussion base
for a new version of the freeciv protocol.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "There are three ways to get something done. Do it yourself, hire someone
  to do it for you or forbid your kids to do it."

Attachment: delta3-stripped.diff.bz2
Description: delta3-stripped.diff.bz2


[Prev in Thread] Current Thread [Next in Thread]