00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "../game/q_shared.h"
00024 #include "../qcommon/qcommon.h"
00025 #include "server.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 static void SV_Netchan_Encode( client_t *client, msg_t *msg ) {
00037 long reliableAcknowledge, i, index;
00038 byte key, *string;
00039 int srdc, sbit, soob;
00040
00041 if ( msg->cursize < SV_ENCODE_START ) {
00042 return;
00043 }
00044
00045 srdc = msg->readcount;
00046 sbit = msg->bit;
00047 soob = msg->oob;
00048
00049 msg->bit = 0;
00050 msg->readcount = 0;
00051 msg->oob = 0;
00052
00053 reliableAcknowledge = MSG_ReadLong(msg);
00054
00055 msg->oob = soob;
00056 msg->bit = sbit;
00057 msg->readcount = srdc;
00058
00059 string = (byte *)client->lastClientCommandString;
00060 index = 0;
00061
00062 key = client->challenge ^ client->netchan.outgoingSequence;
00063 for (i = SV_ENCODE_START; i < msg->cursize; i++) {
00064
00065 if (!string[index])
00066 index = 0;
00067 if (string[index] > 127 || string[index] == '%') {
00068 key ^= '.' << (i & 1);
00069 }
00070 else {
00071 key ^= string[index] << (i & 1);
00072 }
00073 index++;
00074
00075 *(msg->data + i) = *(msg->data + i) ^ key;
00076 }
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static void SV_Netchan_Decode( client_t *client, msg_t *msg ) {
00091 int serverId, messageAcknowledge, reliableAcknowledge;
00092 int i, index, srdc, sbit, soob;
00093 byte key, *string;
00094
00095 srdc = msg->readcount;
00096 sbit = msg->bit;
00097 soob = msg->oob;
00098
00099 msg->oob = 0;
00100
00101 serverId = MSG_ReadLong(msg);
00102 messageAcknowledge = MSG_ReadLong(msg);
00103 reliableAcknowledge = MSG_ReadLong(msg);
00104
00105 msg->oob = soob;
00106 msg->bit = sbit;
00107 msg->readcount = srdc;
00108
00109 string = (byte *)client->reliableCommands[ reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ];
00110 index = 0;
00111
00112 key = client->challenge ^ serverId ^ messageAcknowledge;
00113 for (i = msg->readcount + SV_DECODE_START; i < msg->cursize; i++) {
00114
00115 if (!string[index])
00116 index = 0;
00117 if (string[index] > 127 || string[index] == '%') {
00118 key ^= '.' << (i & 1);
00119 }
00120 else {
00121 key ^= string[index] << (i & 1);
00122 }
00123 index++;
00124
00125 *(msg->data + i) = *(msg->data + i) ^ key;
00126 }
00127 }
00128
00129
00130
00131
00132
00133
00134 void SV_Netchan_TransmitNextFragment( client_t *client ) {
00135 Netchan_TransmitNextFragment( &client->netchan );
00136 if (!client->netchan.unsentFragments)
00137 {
00138
00139 if (!client->netchan_end_queue) {
00140 Com_Error(ERR_DROP, "netchan queue is not properly initialized in SV_Netchan_TransmitNextFragment\n");
00141 }
00142
00143 if (client->netchan_start_queue) {
00144 netchan_buffer_t *netbuf;
00145 Com_DPrintf("#462 Netchan_TransmitNextFragment: popping a queued message for transmit\n");
00146 netbuf = client->netchan_start_queue;
00147 SV_Netchan_Encode( client, &netbuf->msg );
00148 Netchan_Transmit( &client->netchan, netbuf->msg.cursize, netbuf->msg.data );
00149
00150 client->netchan_start_queue = netbuf->next;
00151 if (!client->netchan_start_queue) {
00152 Com_DPrintf("#462 Netchan_TransmitNextFragment: emptied queue\n");
00153 client->netchan_end_queue = &client->netchan_start_queue;
00154 }
00155 else
00156 Com_DPrintf("#462 Netchan_TransmitNextFragment: remaining queued message\n");
00157 Z_Free(netbuf);
00158 }
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 void SV_Netchan_Transmit( client_t *client, msg_t *msg) {
00175 MSG_WriteByte( msg, svc_EOF );
00176 if (client->netchan.unsentFragments) {
00177 netchan_buffer_t *netbuf;
00178 Com_DPrintf("#462 SV_Netchan_Transmit: unsent fragments, stacked\n");
00179 netbuf = (netchan_buffer_t *)Z_Malloc(sizeof(netchan_buffer_t));
00180
00181 MSG_Copy(&netbuf->msg, netbuf->msgBuffer, sizeof( netbuf->msgBuffer ), msg);
00182 netbuf->next = NULL;
00183
00184 *client->netchan_end_queue = netbuf;
00185 client->netchan_end_queue = &(*client->netchan_end_queue)->next;
00186
00187 Netchan_TransmitNextFragment(&client->netchan);
00188 } else {
00189 SV_Netchan_Encode( client, msg );
00190 Netchan_Transmit( &client->netchan, msg->cursize, msg->data );
00191 }
00192 }
00193
00194
00195
00196
00197
00198
00199 qboolean SV_Netchan_Process( client_t *client, msg_t *msg ) {
00200 int ret;
00201 ret = Netchan_Process( &client->netchan, msg );
00202 if (!ret)
00203 return qfalse;
00204 SV_Netchan_Decode( client, msg );
00205 return qtrue;
00206 }
00207