From 425decdf7e9284d15aa726e3ae96b9942fb0e3ea Mon Sep 17 00:00:00 2001 From: IronClawTrem Date: Sun, 16 Feb 2020 03:40:06 +0000 Subject: create tremded branch --- src/client/client.h | 716 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 716 insertions(+) create mode 100644 src/client/client.h (limited to 'src/client/client.h') diff --git a/src/client/client.h b/src/client/client.h new file mode 100644 index 0000000..2474a3d --- /dev/null +++ b/src/client/client.h @@ -0,0 +1,716 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2013 Darklegion Development +Copyright (C) 2015-2019 GrangerHub + +This file is part of Tremulous. + +Tremulous is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, see + +=========================================================================== +*/ +// client.h -- primary header for client + +#ifndef _CLIENT_H_ +#define _CLIENT_H_ + +#ifdef USE_VOIP +#include +#endif + +#include "cgame/cg_public.h" +#include "qcommon/alternatePlayerstate.h" +#include "qcommon/cmd.h" +#include "qcommon/crypto.h" +#include "qcommon/cvar.h" +#include "qcommon/files.h" +#include "qcommon/huffman.h" +#include "qcommon/msg.h" +#include "qcommon/net.h" +#include "qcommon/q_shared.h" +#include "qcommon/qcommon.h" +#include "qcommon/vm.h" +#include "renderercommon/tr_public.h" +#include "sys/sys_shared.h" +#include "ui/ui_public.h" + +#include "cl_curl.h" +#include "keys.h" +#include "snd_public.h" + +struct alternateEntityState_t { + int number; // entity index + int eType; // entityType_t + int eFlags; + + trajectory_t pos; // for calculating position + trajectory_t apos; // for calculating angles + + int time; + int time2; + + vec3_t origin; + vec3_t origin2; + + vec3_t angles; + vec3_t angles2; + + int otherEntityNum; // shotgun sources, etc + int otherEntityNum2; + + int groundEntityNum; // ENTITYNUM_NONE = in air + + int constantLight; // r + (g<<8) + (b<<16) + (intensity<<24) + int loopSound; // constantly loop this sound + + int modelindex; + int modelindex2; + int clientNum; // 0 to (MAX_CLIENTS - 1), for players and corpses + int frame; + + int solid; // for client side prediction, trap_linkentity sets this properly + + int event; // impulse events -- muzzle flashes, footsteps, etc + int eventParm; + + // for players + int misc; // bit flags + int weapon; // determines weapon and flash model, etc + int legsAnim; // mask off ANIM_TOGGLEBIT + int torsoAnim; // mask off ANIM_TOGGLEBIT + + int generic1; +}; + +struct alternateSnapshot_t { + int snapFlags; // SNAPFLAG_RATE_DELAYED, etc + int ping; + + int serverTime; // server time the message is valid for (in msec) + + byte areamask[MAX_MAP_AREA_BYTES]; // portalarea visibility bits + + alternatePlayerState_t ps; // complete information about the current player at this time + + int numEntities; // all of the entities that need to be presented + alternateEntityState_t entities[MAX_ENTITIES_IN_SNAPSHOT]; // at the time of this snapshot + + int numServerCommands; // text based server commands to execute when this + int serverCommandSequence; // snapshot becomes current +}; + +// file full of random crap that gets used to create cl_guid +#define QKEY_FILE "qkey" +#define QKEY_SIZE 2048 + +#define RETRANSMIT_TIMEOUT 3000 // time between connection packet retransmits + +// snapshots are a view of the server at a given time +struct clSnapshot_t { + bool valid; // cleared if delta parsing was invalid + int snapFlags; // rate delayed and dropped commands + + int serverTime; // server time the message is valid for (in msec) + + int messageNum; // copied from netchan->incoming_sequence + int deltaNum; // messageNum the delta is from + int ping; // time from when cmdNum-1 was sent to time packet was reeceived + byte areamask[MAX_MAP_AREA_BYTES]; // portalarea visibility bits + + int cmdNum; // the next cmdNum the server is expecting + playerState_t ps; // complete information about the current player at this time + alternatePlayerState_t alternatePs; // complete information about the current player at this time + + int numEntities; // all of the entities that need to be presented + int parseEntitiesNum; // at the time of this snapshot + + int serverCommandNum; // execute all commands up to this before + // making the snapshot current +}; + +/* +============================================================================= + +the clientActive_t structure is wiped completely at every +new gamestate_t, potentially several times during an established connection + +============================================================================= +*/ + +struct outPacket_t { + int p_cmdNumber; // cl.cmdNumber when packet was sent + int p_serverTime; // usercmd->serverTime when packet was sent + int p_realtime; // cls.realtime when packet was sent +}; + +// the parseEntities array must be large enough to hold PACKET_BACKUP frames of +// entities, so that when a delta compressed message arives from the server +// it can be un-deltad from the original +#define MAX_PARSE_ENTITIES (PACKET_BACKUP * MAX_SNAPSHOT_ENTITIES) + +extern int g_console_field_width; + +struct clientActive_t { + int timeoutcount; // it requres several frames in a timeout condition + // to disconnect, preventing debugging breaks from + // causing immediate disconnects on continue + clSnapshot_t snap; // latest received from server + + int serverTime; // may be paused during play + int oldServerTime; // to prevent time from flowing bakcwards + int oldFrameServerTime; // to check tournament restarts + int serverTimeDelta; // cl.serverTime = cls.realtime + cl.serverTimeDelta + // this value changes as net lag varies + bool extrapolatedSnapshot; // set if any cgame frame has been forced to extrapolate + // cleared when CL_AdjustTimeDelta looks at it + bool newSnapshots; // set on parse of any valid packet + + gameState_t gameState; // configstrings + char mapname[MAX_QPATH]; // extracted from CS_SERVERINFO + + int parseEntitiesNum; // index (not anded off) into cl_parse_entities[] + + int mouseDx[2], mouseDy[2]; // added to by mouse events + int mouseIndex; + int joystickAxis[MAX_JOYSTICK_AXIS]; // set by joystick events + + // cgame communicates a few values to the client system + int cgameUserCmdValue; // current weapon to add to usercmd_t + float cgameSensitivity; + + // cmds[cmdNumber] is the predicted command, [cmdNumber-1] is the last + // properly generated command + usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds + int cmdNumber; // incremented each frame, because multiple + // frames may need to be packed into a single packet + + outPacket_t outPackets[PACKET_BACKUP]; // information about each packet we have sent out + + // the client maintains its own idea of view angles, which are + // sent to the server each frame. It is cleared to 0 upon entering each level. + // the server sends a delta each frame which is added to the locally + // tracked view angles to account for standing on rotating objects, + // and teleport direction changes + vec3_t viewangles; + + int serverId; // included in each client message so the server + // can tell if it is for a prior map_restart + // big stuff at end of structure so most offsets are 15 bits or less + clSnapshot_t snapshots[PACKET_BACKUP]; + + entityState_t entityBaselines[MAX_GENTITIES]; // for delta compression when not in previous frame + + entityState_t parseEntities[MAX_PARSE_ENTITIES]; +}; + +extern clientActive_t cl; + +/* +============================================================================= + +the clientConnection_t structure is wiped when disconnecting from a server, +either to go to a full screen console, play a demo, or connect to a different server + +A connection can be to either a server through the network layer or a +demo through a file. + +============================================================================= +*/ + +#define MAX_TIMEDEMO_DURATIONS 4096 + +struct clientConnection_t { + connstate_t state; // connection status + + int clientNum; + int lastPacketSentTime; // for retransmits during connection + int lastPacketTime; // for timeouts + + char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect) + netadr_t serverAddress; + int connectTime; // for connection retransmits + int connectPacketCount; // for display on connection dialog + char serverMessage[MAX_STRING_TOKENS]; // for display on connection dialog + + int challenge; // from the server to use for connecting + char challenge2[33]; + bool sendSignature; + int checksumFeed; // from the server for checksum calculations + + // these are our reliable messages that go to the server + int reliableSequence; + int reliableAcknowledge; // the last one the server has executed + char reliableCommands[MAX_RELIABLE_COMMANDS][MAX_STRING_CHARS]; + + // server message (unreliable) and command (reliable) sequence + // numbers are NOT cleared at level changes, but continue to + // increase as long as the connection is valid + + // message sequence is used by both the network layer and the + // delta compression layer + int serverMessageSequence; + + // reliable messages received from server + int serverCommandSequence; + int lastExecutedServerCommand; // last server command grabbed or executed with CL_GetServerCommand + char serverCommands[MAX_RELIABLE_COMMANDS][MAX_STRING_CHARS]; + + // file transfer from server + fileHandle_t download; + char downloadTempName[MAX_OSPATH]; + char downloadName[MAX_OSPATH]; + + // XXX Refactor this -vjr + bool cURLEnabled; + bool cURLUsed; + bool cURLDisconnected; + + char downloadURL[MAX_OSPATH]; + CURL *downloadCURL; + CURLM *downloadCURLM; + bool activeCURLNotGameRelated; + + int sv_allowDownload; + char sv_dlURL[MAX_CVAR_VALUE_STRING]; + int downloadNumber; + int downloadBlock; // block we are waiting for + int downloadCount; // how many bytes we got + int downloadSize; // how many bytes we got + char downloadList[MAX_INFO_STRING]; // list of paks we need to download + bool downloadRestart; // if true, we need to do another FS_Restart because we downloaded a pak + char newsString[MAX_NEWS_STRING]; + + // demo information + char demoName[MAX_QPATH]; + bool spDemoRecording; + bool demorecording; + bool demoplaying; + bool demowaiting; // don't record until a non-delta message is received + bool firstDemoFrameSkipped; + fileHandle_t demofile; + + int timeDemoFrames; // counter of rendered frames + int timeDemoStart; // cls.realtime before first frame + int timeDemoBaseTime; // each frame will be at this time + frameNum * 50 + int timeDemoLastFrame; // time the last frame was rendered + int timeDemoMinDuration; // minimum frame duration + int timeDemoMaxDuration; // maximum frame duration + unsigned char timeDemoDurations[MAX_TIMEDEMO_DURATIONS]; // log of frame durations + + float aviVideoFrameRemainder; + float aviSoundFrameRemainder; + +#ifdef USE_VOIP + bool voipEnabled; + bool voipCodecInitialized; + + // incoming data... + // !!! FIXME: convert from parallel arrays to array of a struct. + OpusDecoder *opusDecoder[MAX_CLIENTS]; + byte voipIncomingGeneration[MAX_CLIENTS]; + int voipIncomingSequence[MAX_CLIENTS]; + float voipGain[MAX_CLIENTS]; + bool voipIgnore[MAX_CLIENTS]; + bool voipMuteAll; + + // outgoing data... + // if voipTargets[i / 8] & (1 << (i % 8)), + // then we are sending to clientnum i. + uint8_t voipTargets[(MAX_CLIENTS + 7) / 8]; + uint8_t voipFlags; + OpusEncoder *opusEncoder; + int voipOutgoingDataSize; + int voipOutgoingDataFrames; + int voipOutgoingSequence; + byte voipOutgoingGeneration; + byte voipOutgoingData[1024]; + float voipPower; +#endif + + // big stuff at end of structure so most offsets are 15 bits or less + netchan_t netchan; +}; + +extern clientConnection_t clc; + +/* +================================================================== + +the clientStatic_t structure is never wiped, and is used even when +no client connection is active at all +(except when CL_Shutdown is called) + +================================================================== +*/ + +struct ping_t { + netadr_t adr; + int start; + int time; + char info[MAX_INFO_STRING]; +}; + +#define MAX_FEATLABEL_CHARS 32 +struct serverInfo_t { + netadr_t adr; + char hostName[MAX_HOSTNAME_LENGTH]; + char mapName[MAX_NAME_LENGTH]; + char game[MAX_NAME_LENGTH]; + char label[MAX_FEATLABEL_CHARS]; // for featured servers, NULL otherwise + int netType; + int gameType; + int clients; + int maxClients; + int minPing; + int maxPing; + int ping; + bool visible; +}; + +struct clientStatic_t { + // when the server clears the hunk, all of these must be restarted + bool rendererStarted; + bool soundStarted; + bool soundRegistered; + bool uiStarted; + bool cgameStarted; + + int framecount; + int frametime; // msec since last frame + + int realtime; // ignores pause + int realFrametime; // ignoring pause, so console always works + + // master server sequence information + int numAlternateMasterPackets[3]; + unsigned int receivedAlternateMasterPackets[3]; // bitfield + + int numlocalservers; + serverInfo_t localServers[MAX_OTHER_SERVERS]; + + int numglobalservers; + serverInfo_t globalServers[MAX_GLOBAL_SERVERS]; + // additional global servers + int numGlobalServerAddresses; + netadr_t globalServerAddresses[MAX_GLOBAL_SERVERS]; + + int numfavoriteservers; + serverInfo_t favoriteServers[MAX_OTHER_SERVERS]; + + int pingUpdateSource; // source currently pinging or updating + + // update server info + netadr_t updateServer; + char updateChallenge[MAX_TOKEN_CHARS]; + char updateInfoString[MAX_INFO_STRING]; + + netadr_t authorizeServer; + + // rendering info + glconfig_t glconfig; + qhandle_t charSetShader; + qhandle_t whiteShader; + qhandle_t consoleShader; + + vm_t *cgame; + int cgInterface; // 0 == gpp, 2 == 1.1.0 + + vm_t *ui; + int uiInterface; + + struct { + struct rsa_public_key public_key; + struct rsa_private_key private_key; + } rsa; +}; + +extern clientStatic_t cls; + +extern char cl_oldGame[MAX_QPATH]; +extern bool cl_oldGameSet; + +//============================================================================= + +extern refexport_t re; // interface to refresh .dll + +// +// cvars +// +extern cvar_t *cl_nodelta; +extern cvar_t *cl_debugMove; +extern cvar_t *cl_noprint; +extern cvar_t *cl_timegraph; +extern cvar_t *cl_maxpackets; +extern cvar_t *cl_packetdup; +extern cvar_t *cl_shownet; +extern cvar_t *cl_showSend; +extern cvar_t *cl_timeNudge; +extern cvar_t *cl_showTimeDelta; +extern cvar_t *cl_freezeDemo; + +extern cvar_t *cl_yawspeed; +extern cvar_t *cl_pitchspeed; +extern cvar_t *cl_run; +extern cvar_t *cl_anglespeedkey; + +extern cvar_t *cl_sensitivity; +extern cvar_t *cl_freelook; + +extern cvar_t *cl_mouseAccel; +extern cvar_t *cl_mouseAccelOffset; +extern cvar_t *cl_mouseAccelStyle; +extern cvar_t *cl_showMouseRate; + +extern cvar_t *m_pitch; +extern cvar_t *m_yaw; +extern cvar_t *m_forward; +extern cvar_t *m_side; +extern cvar_t *m_filter; + +extern cvar_t *j_pitch; +extern cvar_t *j_yaw; +extern cvar_t *j_forward; +extern cvar_t *j_side; +extern cvar_t *j_up; +extern cvar_t *j_pitch_axis; +extern cvar_t *j_yaw_axis; +extern cvar_t *j_forward_axis; +extern cvar_t *j_side_axis; +extern cvar_t *j_up_axis; + +extern cvar_t *cl_timedemo; +extern cvar_t *cl_aviFrameRate; +extern cvar_t *cl_aviMotionJpeg; + +extern cvar_t *cl_activeAction; + +extern cvar_t *cl_allowDownload; +extern cvar_t *cl_downloadMethod; +extern cvar_t *cl_conXOffset; +extern cvar_t *cl_inGameVideo; + +extern cvar_t *cl_lanForcePackets; +extern cvar_t *cl_autoRecordDemo; + +extern cvar_t *cl_clantag; + +extern cvar_t *cl_consoleKeys; + +#ifdef USE_MUMBLE +extern cvar_t *cl_useMumble; +extern cvar_t *cl_mumbleScale; +#endif + +#ifdef USE_VOIP +// cl_voipSendTarget is a string: "all" to broadcast to everyone, "none" to +// send to no one, or a comma-separated list of client numbers: +// "0,7,2,23" ... an empty string is treated like "all". +extern cvar_t *cl_voipUseVAD; +extern cvar_t *cl_voipVADThreshold; +extern cvar_t *cl_voipSend; +extern cvar_t *cl_voipSendTarget; +extern cvar_t *cl_voipGainDuringCapture; +extern cvar_t *cl_voipCaptureMult; +extern cvar_t *cl_voipShowMeter; +extern cvar_t *cl_voip; + +// 20ms at 48k +#define VOIP_MAX_FRAME_SAMPLES (20 * 48) + +// 3 frame is 60ms of audio, the max opus will encode at once +#define VOIP_MAX_PACKET_FRAMES 3 +#define VOIP_MAX_PACKET_SAMPLES (VOIP_MAX_FRAME_SAMPLES * VOIP_MAX_PACKET_FRAMES) +#endif + +extern cvar_t *cl_rsaAuth; + +//================================================= + +// +// cl_main +// + +void CL_Init(void); +void CL_AddReliableCommand(const char *cmd, bool isDisconnectCmd); + +void CL_StartHunkUsers(bool rendererOnly); + +void CL_Disconnect_f(void); +void CL_NextDemo(void); +void CL_ReadDemoMessage(void); +demoState_t CL_DemoState(void); +int CL_DemoPos(void); +void CL_DemoName(char *buffer, int size); +void CL_StopRecord_f(void); + +void CL_InitDownloads(void); +void CL_NextDownload(void); + +void CL_GetPing(int n, char *buf, int buflen, int *pingtime); +void CL_GetPingInfo(int n, char *buf, int buflen); +void CL_ClearPing(int n); +int CL_GetPingQueueCount(void); + +bool CL_ServerStatus(char *serverAddress, char *serverStatusString, int maxLen); + +bool CL_CheckPaused(void); + +// +// cl_input +// +typedef struct { + int down[2]; // key nums holding it down + unsigned downtime; // msec timestamp + unsigned msec; // msec down this frame if both a down and up happened + bool active; // current state + bool wasPressed; // set when down, not cleared when up +} kbutton_t; + +void CL_InitInput(void); +void CL_ShutdownInput(void); +void CL_SendCmd(void); +void CL_ClearState(void); +void CL_ReadPackets(void); + +void CL_WritePacket(void); +//void IN_CenterView(void); + +int Key_StringToKeynum(const char *str); +const char *Key_KeynumToString(int keynum); + +// +// cl_parse.c +// +extern bool cl_connectedToPureServer; +extern bool cl_connectedToCheatServer; + +#ifdef USE_VOIP +void CL_Voip_f(void); +#endif + +void CL_SystemInfoChanged(void); +void CL_ParseServerMessage(msg_t *msg); + +//==================================================================== + +bool CL_UpdateVisiblePings_f(int source); + +// +// console +// +void Con_DrawCharacter(int cx, int line, int num); + +void Con_CheckResize(void); +void Con_MessageModesInit(void); +void CL_ProtocolSpecificCommandsInit(void); +void Con_Init(void); +void Con_Shutdown(void); +void Con_Clear_f(void); +void Con_ToggleConsole_f(void); +void Con_ClearNotify(void); +void Con_RunConsole(void); +void Con_DrawConsole(void); +void Con_PageUp(void); +void Con_PageDown(void); +void Con_Top(void); +void Con_Bottom(void); +void Con_Close(void); + +void CL_LoadConsoleHistory(void); +void CL_SaveConsoleHistory(void); + +// +// cl_scrn.c +// +void SCR_Init(void); +void SCR_UpdateScreen(void); + +void SCR_DebugGraph(float value); + +int SCR_GetBigStringWidth(const char *str); // returns in virtual 640x480 coordinates + +void SCR_AdjustFrom640(float *x, float *y, float *w, float *h); +void SCR_FillRect(float x, float y, float width, float height, const float *color); +void SCR_DrawPic(float x, float y, float width, float height, qhandle_t hShader); +void SCR_DrawNamedPic(float x, float y, float width, float height, const char *picname); + +void SCR_DrawBigString(int x, int y, const char *s, float alpha, + bool noColorEscape); // draws a string with embedded color control characters with fade +void SCR_DrawBigStringColor( + int x, int y, const char *s, vec4_t color, bool noColorEscape); // ignores embedded color control characters +void SCR_DrawSmallStringExt(int x, int y, const char *string, float *setColor, bool forceColor, bool noColorEscape); +void SCR_DrawSmallChar(int x, int y, int ch); + +// +// cl_cin.c +// + +void CL_PlayCinematic_f(void); +void SCR_DrawCinematic(void); +void SCR_RunCinematic(void); +void SCR_StopCinematic(void); +int CIN_PlayCinematic(const char *arg0, int xpos, int ypos, int width, int height, int bits); +e_status CIN_StopCinematic(int handle); +e_status CIN_RunCinematic(int handle); +void CIN_DrawCinematic(int handle); +void CIN_SetExtents(int handle, int x, int y, int w, int h); +void CIN_UploadCinematic(int handle); +void CIN_CloseAllVideos(void); + +// +// cl_cgame.c +// +void CL_InitCGame(void); +void CL_ShutdownCGame(void); +bool CL_GameCommand(void); +void CL_GameConsoleText(void); +void CL_CGameRendering(stereoFrame_t stereo); +void CL_SetCGameTime(void); +void CL_FirstSnapshot(void); +void CL_ShaderStateChanged(void); + +// +// cl_ui.c +// +void CL_InitUI(void); +void CL_ShutdownUI(void); +int Key_GetCatcher(void); +void Key_SetCatcher(int catcher); +void LAN_LoadCachedServers(void); +void LAN_SaveServersToCache(void); + +// +// cl_net_chan.c +// +void CL_Netchan_Transmit(netchan_t *chan, msg_t *msg); // int length, const byte *data ); +bool CL_Netchan_Process(netchan_t *chan, msg_t *msg); + +// +// cl_avi.c +// +bool CL_OpenAVIForWriting(const char *filename); +void CL_TakeVideoFrame(void); +void CL_WriteAVIVideoFrame(const byte *imageBuffer, int size); +void CL_WriteAVIAudioFrame(const byte *pcmBuffer, int size); +bool CL_CloseAVI(void); +bool CL_VideoRecording(void); + +// +// cl_main.c +// +void CL_WriteDemoMessage(msg_t *msg, int headerBytes); +int CL_ScaledMilliseconds(void); + +#endif -- cgit