]> git.xonotic.org Git - xonotic/darkplaces.git/blob - protocol.c
cvar: Rename Cvar_RegisterAlias to Cvar_RegisterVirtual
[xonotic/darkplaces.git] / protocol.c
1 #include "quakedef.h"
2
3 // this is 88 bytes (must match entity_state_t in protocol.h)
4 entity_state_t defaultstate =
5 {
6         // ! means this is not sent to client
7         0,//double time; // ! time this state was built (used on client for interpolation)
8         {0,0,0},//float netcenter[3]; // ! for network prioritization, this is the center of the bounding box (which may differ from the origin)
9         {0,0,0},//float origin[3];
10         {0,0,0},//float angles[3];
11         0,//int effects;
12         0,//unsigned int customizeentityforclient; // !
13         0,//unsigned short number; // entity number this state is for
14         0,//unsigned short modelindex;
15         0,//unsigned short frame;
16         0,//unsigned short tagentity;
17         0,//unsigned short specialvisibilityradius; // ! larger if it has effects/light
18         0,//unsigned short viewmodelforclient; // !
19         0,//unsigned short exteriormodelforclient; // ! not shown if first person viewing from this entity, shown in all other cases
20         0,//unsigned short nodrawtoclient; // !
21         0,//unsigned short drawonlytoclient; // !
22         0,//unsigned short traileffectnum;
23         {0,0,0,0},//unsigned short light[4]; // color*256 (0.00 to 255.996), and radius*1
24         ACTIVE_NOT,//unsigned char active; // true if a valid state
25         0,//unsigned char lightstyle;
26         0,//unsigned char lightpflags;
27         0,//unsigned char colormap;
28         0,//unsigned char skin; // also chooses cubemap for rtlights if lightpflags & LIGHTPFLAGS_FULLDYNAMIC
29         255,//unsigned char alpha;
30         16,//unsigned char scale;
31         0,//unsigned char glowsize;
32         254,//unsigned char glowcolor;
33         0,//unsigned char flags;
34         0,//unsigned char internaleffects; // INTEF_FLAG1QW and so on
35         0,//unsigned char tagindex;
36         {32, 32, 32},//unsigned char colormod[3];
37         {32, 32, 32},//unsigned char glowmod[3];
38 };
39
40 // LadyHavoc: I own protocol ranges 96, 97, 3500-3599
41
42 struct protocolversioninfo_s
43 {
44         int number;
45         protocolversion_t version;
46         const char *name;
47 }
48 protocolversioninfo[] =
49 {
50         { 3504, PROTOCOL_DARKPLACES7 , "DP7"},
51         { 3503, PROTOCOL_DARKPLACES6 , "DP6"},
52         { 3502, PROTOCOL_DARKPLACES5 , "DP5"},
53         { 3501, PROTOCOL_DARKPLACES4 , "DP4"},
54         { 3500, PROTOCOL_DARKPLACES3 , "DP3"},
55         {   97, PROTOCOL_DARKPLACES2 , "DP2"},
56         {   96, PROTOCOL_DARKPLACES1 , "DP1"},
57         {   15, PROTOCOL_QUAKEDP     , "QUAKEDP"},
58         {   15, PROTOCOL_QUAKE       , "QUAKE"},
59         {   28, PROTOCOL_QUAKEWORLD  , "QW"},
60         {  250, PROTOCOL_NEHAHRAMOVIE, "NEHAHRAMOVIE"},
61         {10000, PROTOCOL_NEHAHRABJP  , "NEHAHRABJP"},
62         {10001, PROTOCOL_NEHAHRABJP2 , "NEHAHRABJP2"},
63         {10002, PROTOCOL_NEHAHRABJP3 , "NEHAHRABJP3"},
64         {    0, PROTOCOL_UNKNOWN     , NULL}
65 };
66
67 protocolversion_t Protocol_EnumForName(const char *s)
68 {
69         int i;
70         for (i = 0;protocolversioninfo[i].name;i++)
71                 if (!strcasecmp(s, protocolversioninfo[i].name))
72                         return protocolversioninfo[i].version;
73         return PROTOCOL_UNKNOWN;
74 }
75
76 const char *Protocol_NameForEnum(protocolversion_t p)
77 {
78         int i;
79         for (i = 0;protocolversioninfo[i].name;i++)
80                 if (protocolversioninfo[i].version == p)
81                         return protocolversioninfo[i].name;
82         return "UNKNOWN";
83 }
84
85 protocolversion_t Protocol_EnumForNumber(int n)
86 {
87         int i;
88         for (i = 0;protocolversioninfo[i].name;i++)
89                 if (protocolversioninfo[i].number == n)
90                         return protocolversioninfo[i].version;
91         return PROTOCOL_UNKNOWN;
92 }
93
94 int Protocol_NumberForEnum(protocolversion_t p)
95 {
96         int i;
97         for (i = 0;protocolversioninfo[i].name;i++)
98                 if (protocolversioninfo[i].version == p)
99                         return protocolversioninfo[i].number;
100         return 0;
101 }
102
103 void Protocol_Names(char *buffer, size_t buffersize)
104 {
105         int i;
106         if (buffersize < 1)
107                 return;
108         buffer[0] = 0;
109         for (i = 0;protocolversioninfo[i].name;i++)
110         {
111                 if (i > 1)
112                         strlcat(buffer, " ", buffersize);
113                 strlcat(buffer, protocolversioninfo[i].name, buffersize);
114         }
115 }
116
117 void Protocol_UpdateClientStats(const int *stats)
118 {
119         int i;
120         // update the stats array and set deltabits for any changed stats
121         for (i = 0;i < MAX_CL_STATS;i++)
122         {
123                 if (host_client->stats[i] != stats[i])
124                 {
125                         host_client->statsdeltabits[i >> 3] |= 1 << (i & 7);
126                         host_client->stats[i] = stats[i];
127                 }
128         }
129 }
130
131 // only a few stats are within the 32 stat limit of Quake, and most of them
132 // are sent every frame in svc_clientdata messages, so we only send the
133 // remaining ones here
134 static const int sendquakestats[] =
135 {
136 // quake did not send these secrets/monsters stats in this way, but doing so
137 // allows a mod to increase STAT_TOTALMONSTERS during the game, and ensures
138 // that STAT_SECRETS and STAT_MONSTERS are always correct (even if a client
139 // didn't receive an svc_foundsecret or svc_killedmonster), which may be most
140 // valuable if randomly seeking around in a demo
141 STAT_TOTALSECRETS, // never changes during game
142 STAT_TOTALMONSTERS, // changes in some mods
143 STAT_SECRETS, // this makes svc_foundsecret unnecessary
144 STAT_MONSTERS, // this makes svc_killedmonster unnecessary
145 STAT_VIEWHEIGHT, // sent just for FTEQW clients
146 STAT_VIEWZOOM, // this rarely changes
147 -1,
148 };
149
150 void Protocol_WriteStatsReliable(void)
151 {
152         int i, j;
153         if (!host_client->netconnection)
154                 return;
155         // detect changes in stats and write reliable messages
156         // this only deals with 32 stats because the older protocols which use
157         // this function can only cope with 32 stats,
158         // they also do not support svc_updatestatubyte which was introduced in
159         // DP6 protocol (except for QW)
160         for (j = 0;sendquakestats[j] >= 0;j++)
161         {
162                 i = sendquakestats[j];
163                 // check if this bit is set
164                 if (host_client->statsdeltabits[i >> 3] & (1 << (i & 7)))
165                 {
166                         host_client->statsdeltabits[i >> 3] -= (1 << (i & 7));
167                         // send the stat as a byte if possible
168                         if (sv.protocol == PROTOCOL_QUAKEWORLD)
169                         {
170                                 if (host_client->stats[i] >= 0 && host_client->stats[i] < 256)
171                                 {
172                                         MSG_WriteByte(&host_client->netconnection->message, qw_svc_updatestat);
173                                         MSG_WriteByte(&host_client->netconnection->message, i);
174                                         MSG_WriteByte(&host_client->netconnection->message, host_client->stats[i]);
175                                 }
176                                 else
177                                 {
178                                         MSG_WriteByte(&host_client->netconnection->message, qw_svc_updatestatlong);
179                                         MSG_WriteByte(&host_client->netconnection->message, i);
180                                         MSG_WriteLong(&host_client->netconnection->message, host_client->stats[i]);
181                                 }
182                         }
183                         else
184                         {
185                                 // this could make use of svc_updatestatubyte in DP6 and later
186                                 // protocols but those protocols do not use this function
187                                 MSG_WriteByte(&host_client->netconnection->message, svc_updatestat);
188                                 MSG_WriteByte(&host_client->netconnection->message, i);
189                                 MSG_WriteLong(&host_client->netconnection->message, host_client->stats[i]);
190                         }
191                 }
192         }
193 }