cl_parse.c

Go to the documentation of this file.
00001 
00006 /*
00007 All original material Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 SERVER CONNECTING MESSAGES
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     /* parse protocol version number */
00074     i = NET_ReadLong(msg);
00075     /* compare versions */
00076     if (i != PROTOCOL_VERSION)
00077         Com_Error(ERR_DROP, "Server returned version %i, not %i", i, PROTOCOL_VERSION);
00078 
00079     /* parse player entity number */
00080     cl.pnum = NET_ReadShort(msg);
00081 
00082     /* get the full level name */
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         /* need to prep refresh at next opportunity */
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     /* isolate the player's name */
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     /* do something appropriate */
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             /* inline models are marked with * as first char followed by the number */
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 ACTION MESSAGES
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     /* parse the message */
00205     if (cmd == -1)
00206         return;
00207 
00208     Com_DPrintf(DEBUG_CLIENT, "command: %s\n", svc_strings[cmd]);
00209 
00210     /* commands */
00211     switch (cmd) {
00212     case svc_nop:
00213 /*      Com_Printf("svc_nop\n"); */
00214         break;
00215 
00216     case svc_disconnect:
00217         NET_ReadString(msg, s, sizeof(s));
00218         Com_Printf("%s\n", s);
00219         CL_Drop();  /* ensure the right menu cvars are set */
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         /* otherwise we would time out */
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             /* skip format strings */
00239             if (s[0] == '^')
00240                 memmove(s, &s[2], sizeof(s) - 2);
00241             /* also print to console */
00242             break;
00243         case PRINT_HUD:
00244             /* all game lib messages or server messages should be printed
00245              * untranslated with BroadcastPrintf or PlayerPrintf */
00246             /* see src/po/OTHER_STRINGS */
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();     /* make sure any stuffed commands are done */
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 }

Generated by  doxygen 1.6.2