00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "../client.h"
00027 #include "cl_localentity.h"
00028 #include "cl_parse.h"
00029 #include "cl_hud.h"
00030 #include "../cl_game.h"
00031 #include "../ui/ui_main.h"
00032 #include "events/e_parse.h"
00033 #include "../multiplayer/mp_chatmessages.h"
00034
00040 static const char *svc_strings[UCHAR_MAX + 1] =
00041 {
00042 "svc_bad",
00043
00044 "svc_nop",
00045 "svc_disconnect",
00046 "svc_reconnect",
00047 "svc_sound",
00048 "svc_print",
00049 "svc_stufftext",
00050 "svc_serverdata",
00051 "svc_configstring",
00052 "svc_event"
00053 };
00054
00055
00056
00057
00058
00059
00060
00064 static void CL_ParseServerData (struct dbuffer *msg)
00065 {
00066 char str[1024];
00067 int i;
00068
00069 Com_DPrintf(DEBUG_CLIENT, "Serverdata packet received.\n");
00070
00071 CL_SetClientState(ca_connected);
00072
00073
00074 i = NET_ReadLong(msg);
00075
00076 if (i != PROTOCOL_VERSION)
00077 Com_Error(ERR_DROP, "Server returned version %i, not %i", i, PROTOCOL_VERSION);
00078
00079
00080 cl.pnum = NET_ReadShort(msg);
00081
00082
00083 NET_ReadString(msg, str, sizeof(str));
00084
00085 Com_DPrintf(DEBUG_CLIENT, "serverdata: pnum %d, level %s\n", cl.pnum, str);
00086
00087 if (cl.pnum >= 0) {
00088
00089 refdef.ready = qfalse;
00090 }
00091 }
00092
00098 static void CL_ParseClientinfo (int player)
00099 {
00100 clientinfo_t *ci = &cl.clientinfo[player];
00101 const char *s = CL_PlayerGetName(player);
00102
00103 Q_strncpyz(ci->cinfo, s, sizeof(ci->cinfo));
00104
00105
00106 Q_strncpyz(ci->name, s, sizeof(ci->name));
00107 }
00108
00114 const char *CL_PlayerGetName (int player)
00115 {
00116 assert(player >= 0);
00117 assert(player < MAX_CLIENTS);
00118
00119 return CL_GetConfigString(CS_PLAYERNAMES + player);
00120 }
00121
00125 static void CL_ParseConfigString (struct dbuffer *msg)
00126 {
00127 const int i = NET_ReadShort(msg);
00128 const char *s = CL_SetConfigString(i, msg);
00129
00130 Com_DPrintf(DEBUG_CLIENT, "configstring %d: %s\n", i, s);
00131
00132
00133 if (i >= CS_MODELS && i < CS_MODELS + MAX_MODELS) {
00134 if (refdef.ready) {
00135 const int index = i - CS_MODELS;
00136 cl.model_draw[index] = R_RegisterModelShort(s);
00137
00138 if (s[0] == '*')
00139 cl.model_clip[index] = CM_InlineModel(cl.mapTiles, s);
00140 else
00141 cl.model_clip[index] = NULL;
00142 }
00143 } else if (i >= CS_PLAYERNAMES && i < CS_PLAYERNAMES + MAX_CLIENTS) {
00144 const int index = i - CS_PLAYERNAMES;
00145 CL_ParseClientinfo(index);
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00161 static void CL_ParseStartSoundPacket (struct dbuffer *msg)
00162 {
00163 vec3_t origin;
00164 char sound[MAX_QPATH];
00165 s_sample_t *sample;
00166
00167 NET_ReadString(msg, sound, sizeof(sound));
00168 NET_ReadPos(msg, origin);
00169
00170 if (sound[strlen(sound) - 1] == '+') {
00171 const int length = strlen(sound) - 1;
00172 char randomSound[MAX_QPATH];
00173 int i = 1;
00174 Com_sprintf(randomSound, sizeof(randomSound), "%s", sound);
00175 randomSound[length + 0] = '\0';
00176 for (;;) {
00177 if (i > 99)
00178 break;
00179
00180 if (FS_CheckFile("sounds/%s%c%c", randomSound, i / 10 + '0', i % 10 + '0') == -1)
00181 break;
00182 i++;
00183 }
00184
00185 sample = S_LoadSample(va("%s%02i", randomSound, (rand() % i) + 1));
00186 } else {
00187 sample = S_LoadSample(sound);
00188 }
00189
00190 S_PlaySample(origin, sample, SOUND_ATTN_NORM, SND_VOLUME_DEFAULT);
00191 }
00192
00199 void CL_ParseServerMessage (svc_ops_t cmd, struct dbuffer *msg)
00200 {
00201 char s[4096];
00202 int i;
00203
00204
00205 if (cmd == -1)
00206 return;
00207
00208 Com_DPrintf(DEBUG_CLIENT, "command: %s\n", svc_strings[cmd]);
00209
00210
00211 switch (cmd) {
00212 case svc_nop:
00213
00214 break;
00215
00216 case svc_disconnect:
00217 NET_ReadString(msg, s, sizeof(s));
00218 Com_Printf("%s\n", s);
00219 CL_Drop();
00220 break;
00221
00222 case svc_reconnect:
00223 NET_ReadString(msg, s, sizeof(s));
00224 Com_Printf("%s\n", s);
00225 CL_Disconnect();
00226 CL_SetClientState(ca_connecting);
00227
00228 cls.connectTime = CL_Milliseconds() - 1500;
00229 break;
00230
00231 case svc_print:
00232 i = NET_ReadByte(msg);
00233 NET_ReadString(msg, s, sizeof(s));
00234 switch (i) {
00235 case PRINT_CHAT:
00236 S_StartLocalSample("misc/talk", SND_VOLUME_DEFAULT);
00237 MP_AddChatMessage(s);
00238
00239 if (s[0] == '^')
00240 memmove(s, &s[2], sizeof(s) - 2);
00241
00242 break;
00243 case PRINT_HUD:
00244
00245
00246
00247 HUD_DisplayMessage(_(s));
00248 break;
00249 default:
00250 break;
00251 }
00252 Com_DPrintf(DEBUG_CLIENT, "svc_print(%d): %s", i, s);
00253 Com_Printf("%s", s);
00254 break;
00255
00256 case svc_stufftext:
00257 NET_ReadString(msg, s, sizeof(s));
00258 Com_DPrintf(DEBUG_CLIENT, "stufftext: %s\n", s);
00259 Cbuf_AddText(s);
00260 break;
00261
00262 case svc_serverdata:
00263 Cbuf_Execute();
00264 CL_ParseServerData(msg);
00265 break;
00266
00267 case svc_configstring:
00268 CL_ParseConfigString(msg);
00269 break;
00270
00271 case svc_sound:
00272 CL_ParseStartSoundPacket(msg);
00273 break;
00274
00275 case svc_event:
00276 CL_ParseEvent(msg);
00277 break;
00278
00279 case svc_bad:
00280 Com_Printf("CL_ParseServerMessage: bad server message %d\n", cmd);
00281 break;
00282
00283 default:
00284 Com_Error(ERR_DROP,"CL_ParseServerMessage: Illegible server message %d", cmd);
00285 }
00286 }