static void SummonActor (int command, int command2, FCommandLine argv) { if (CheckCheatmode ()) return; if (argv.argc() > 1) { PClassActor *type = PClass::FindActor(argv[1]); if (type == NULL) { Printf ("Unknown actor '%s'\n", argv[1]); return; } Net_WriteByte (argv.argc() > 2 ? command2 : command); Net_WriteString (type->TypeName.GetChars()); if (argv.argc () > 2) { Net_WriteWord (atoi (argv[2])); // angle Net_WriteWord ((argv.argc() > 3) ? atoi(argv[3]) : 0); // TID Net_WriteByte ((argv.argc() > 4) ? atoi(argv[4]) : 0); // special for (int i = 5; i < 10; i++) { // args[5] Net_WriteLong((i < argv.argc()) ? atoi(argv[i]) : 0); } } } }
/* * @brief Pumps the command cycle, sending the most recently gathered movement * to the server. */ void Cl_SendCmd(void) { mem_buf_t buf; byte data[128]; if (cls.state <= CL_CONNECTING) return; if (cls.state == CL_CONNECTED) { // send any reliable messages and / or don't timeout if (cls.net_chan.message.size || cls.real_time - cls.net_chan.last_sent > 1000) Netchan_Transmit(&cls.net_chan, NULL, 0); return; } // send a user info update if needed if (cvar_user_info_modified) { Net_WriteByte(&cls.net_chan.message, CL_CMD_USER_INFO); Net_WriteString(&cls.net_chan.message, Cvar_UserInfo()); cvar_user_info_modified = false; } // finalize the current command Cl_FinalizeCmd(); // and write it out Mem_InitBuffer(&buf, data, sizeof(data)); Net_WriteByte(&buf, CL_CMD_MOVE); // let the server know what the last frame we got was, so the next // message can be delta compressed if (!cl.frame.valid || (cls.demo_file && Fs_Tell(cls.demo_file) == 0)) Net_WriteLong(&buf, -1); // no compression else Net_WriteLong(&buf, cl.frame.frame_num); // send this and the previous two cmds in the message, so // if the last packet was dropped, it can be recovered static user_cmd_t null_cmd; cl_cmd_t *cmd = &cl.cmds[(cls.net_chan.outgoing_sequence - 2) & CMD_MASK]; Net_WriteDeltaUserCmd(&buf, &null_cmd, &cmd->cmd); user_cmd_t *old_cmd = &cmd->cmd; cmd = &cl.cmds[(cls.net_chan.outgoing_sequence - 1) & CMD_MASK]; Net_WriteDeltaUserCmd(&buf, old_cmd, &cmd->cmd); old_cmd = &cmd->cmd; cmd = &cl.cmds[(cls.net_chan.outgoing_sequence) & CMD_MASK]; Net_WriteDeltaUserCmd(&buf, old_cmd, &cmd->cmd); // deliver the message Netchan_Transmit(&cls.net_chan, buf.data, buf.size); cl.packet_counter++; // initialize the next command Cl_InitCmd(); }
void D_UserInfoChanged (FBaseCVar *cvar) { UCVarValue val; FString escaped_val; char foo[256]; if (cvar == &autoaim) { if (autoaim < 0.0f) { autoaim = 0.0f; return; } else if (autoaim > 5000.0f) { autoaim = 5000.f; return; } } val = cvar->GetGenericRep (CVAR_String); escaped_val = D_EscapeUserInfo(val.String); if (4 + strlen(cvar->GetName()) + escaped_val.Len() > 256) I_Error ("User info descriptor too big"); mysnprintf (foo, countof(foo), "\\%s\\%s", cvar->GetName(), escaped_val.GetChars()); Net_WriteByte (DEM_UINFCHANGED); Net_WriteString (foo); }
void D_SendServerInfoChange (const FBaseCVar *cvar, UCVarValue value, ECVarType type) { size_t namelen; namelen = strlen (cvar->GetName ()); Net_WriteByte (DEM_SINFCHANGED); Net_WriteByte ((BYTE)(namelen | (type << 6))); Net_WriteBytes ((BYTE *)cvar->GetName (), (int)namelen); switch (type) { case CVAR_Bool: Net_WriteByte (value.Bool); break; case CVAR_Int: Net_WriteLong (value.Int); break; case CVAR_Float: Net_WriteFloat (value.Float); break; case CVAR_String: Net_WriteString (value.String); break; default: break; // Silence GCC } }
static void SummonActor (int command, int command2, FCommandLine argv) { if (CheckCheatmode ()) return; if (argv.argc() > 1) { const PClass *type = PClass::FindClass (argv[1]); if (type == NULL) { Printf ("Unknown class '%s'\n", argv[1]); return; } Net_WriteByte (argv.argc() > 2 ? command2 : command); Net_WriteString (type->TypeName.GetChars()); if (argv.argc () > 2) { Net_WriteWord (atoi (argv[2])); // angle if (argv.argc () > 3) Net_WriteWord (atoi (argv[3])); // TID else Net_WriteWord (0); if (argv.argc () > 4) Net_WriteByte (atoi (argv[4])); // special else Net_WriteByte (0); for(int i = 5; i < 10; i++) { // args[5] if(i < argv.argc()) Net_WriteLong (atoi (argv[i])); else Net_WriteLong (0); } } } }
/** * @brief Sends the user info string to the server over the reliable channel. */ static void Cl_WriteUserInfoCommand(void) { if (cvar_user_info_modified) { cvar_user_info_modified = false; Net_WriteByte(&cls.net_chan.message, CL_CMD_USER_INFO); Net_WriteString(&cls.net_chan.message, Cvar_UserInfo()); } }
/* * @brief A download message has been received from the server. */ static void Cl_ParseDownload(void) { int32_t size, percent; // read the data size = Net_ReadShort(&net_message); percent = Net_ReadByte(&net_message); if (size < 0) { Com_Debug("Server does not have this file\n"); if (cls.download.file) { // if here, we tried to resume a file but the server said no Fs_Close(cls.download.file); cls.download.file = NULL; } Cl_RequestNextDownload(); return; } // open the file if not opened yet if (!cls.download.file) { if (!(cls.download.file = Fs_OpenWrite(cls.download.tempname))) { net_message.read += size; Com_Warn("Failed to open %s\n", cls.download.tempname); Cl_RequestNextDownload(); return; } } Fs_Write(cls.download.file, net_message.data + net_message.read, 1, size); net_message.read += size; if (percent != 100) { Net_WriteByte(&cls.net_chan.message, CL_CMD_STRING); Net_WriteString(&cls.net_chan.message, "nextdl"); } else { Fs_Close(cls.download.file); cls.download.file = NULL; // add new archives to the search path if (Fs_Rename(cls.download.tempname, cls.download.name)) { if (strstr(cls.download.name, ".zip")) { Fs_AddToSearchPath(cls.download.name); } } else { Com_Error(ERR_DROP, "Failed to rename %s\n", cls.download.name); } // get another file if needed Cl_RequestNextDownload(); } }
/* * @brief Client implementation of Cmd_ForwardToServer. Any commands not recognized * locally by the client will be sent to the server. Some will undergo parameter * expansion so that players can use macros for locations, weapons, etc. */ static void Cl_ForwardCmdToServer(void) { if (cls.state <= CL_DISCONNECTED) { Com_Print("%s: Not connected\n", Cmd_Argv(0)); return; } const char *cmd = Cmd_Argv(0); const char *args = Cmd_Args(); Net_WriteByte(&cls.net_chan.message, CL_CMD_STRING); Net_WriteString(&cls.net_chan.message, va("%s %s", cmd, args)); //Com_Debug("Forwarding '%s %s'\n", cmd, args); }
static void ShoveChatStr (const char *str, BYTE who) { FString substBuff; if (str[0] == '/' && (str[1] == 'm' || str[1] == 'M') && (str[2] == 'e' || str[2] == 'E')) { // This is a /me message str += 3; who |= 2; } Net_WriteByte (DEM_SAY); Net_WriteByte (who); if (!chat_substitution || !DoSubstitution (substBuff, str)) { Net_WriteString (str); } else { Net_WriteString (substBuff); } }
//***************************************************************************** // void chat_SendMessage( ULONG ulMode, const char *pszString ) { FString ChatMessage = pszString; // [CW] Substitute the message if necessary. chat_DoSubstitution( ChatMessage ); // If we're the client, let the server handle formatting/sending the msg to other players. if ( NETWORK_GetState( ) == NETSTATE_CLIENT ) { CLIENTCOMMANDS_Say( ulMode, ChatMessage.GetChars( )); return; } if ( demorecording ) { Net_WriteByte( DEM_SAY ); Net_WriteByte( ulMode ); Net_WriteString( ChatMessage.GetChars( )); } else CHAT_PrintChatString( consoleplayer, ulMode, ChatMessage.GetChars( )); }
/** * @brief Writes server_data, config_strings, and baselines once a non-delta * compressed frame arrives from the server. */ static void Cl_WriteDemoHeader(void) { static entity_state_t null_state; mem_buf_t msg; byte buffer[MAX_MSG_SIZE]; // write out messages to hold the startup information Mem_InitBuffer(&msg, buffer, sizeof(buffer)); // write the server data Net_WriteByte(&msg, SV_CMD_SERVER_DATA); Net_WriteShort(&msg, PROTOCOL_MAJOR); Net_WriteShort(&msg, cls.cgame->protocol); Net_WriteByte(&msg, 1); // demo_server byte Net_WriteString(&msg, Cvar_GetString("game")); Net_WriteShort(&msg, cl.client_num); Net_WriteString(&msg, cl.config_strings[CS_NAME]); // and config_strings for (int32_t i = 0; i < MAX_CONFIG_STRINGS; i++) { if (*cl.config_strings[i] != '\0') { if (msg.size + strlen(cl.config_strings[i]) + 32 > msg.max_size) { // write it out const int32_t len = LittleLong((int32_t) msg.size); Fs_Write(cls.demo_file, &len, sizeof(len), 1); Fs_Write(cls.demo_file, msg.data, msg.size, 1); msg.size = 0; } Net_WriteByte(&msg, SV_CMD_CONFIG_STRING); Net_WriteShort(&msg, i); Net_WriteString(&msg, cl.config_strings[i]); } } // and baselines for (size_t i = 0; i < lengthof(cl.entities); i++) { entity_state_t *ent = &cl.entities[i].baseline; if (!ent->number) { continue; } if (msg.size + 64 > msg.max_size) { // write it out const int32_t len = LittleLong((int32_t) msg.size); Fs_Write(cls.demo_file, &len, sizeof(len), 1); Fs_Write(cls.demo_file, msg.data, msg.size, 1); msg.size = 0; } Net_WriteByte(&msg, SV_CMD_BASELINE); Net_WriteDeltaEntity(&msg, &null_state, &cl.entities[i].baseline, true); } Net_WriteByte(&msg, SV_CMD_CBUF_TEXT); Net_WriteString(&msg, "precache 0\n"); // write it to the demo file const int32_t len = LittleLong((int32_t) msg.size); Fs_Write(cls.demo_file, &len, sizeof(len), 1); Fs_Write(cls.demo_file, msg.data, msg.size, 1); Com_Debug(DEBUG_CLIENT, "Demo started\n"); // the rest of the demo file will be individual frames }
/* * @brief Returns true if the file exists, otherwise it attempts to start a download * from the server. */ _Bool Cl_CheckOrDownloadFile(const char *filename) { char cmd[MAX_STRING_CHARS]; if (cls.state == CL_DISCONNECTED) { Com_Print("Not connected\n"); return true; } if (IS_INVALID_DOWNLOAD(filename)) { Com_Warn("Refusing to download \"%s\"\n", filename); return true; } Com_Debug("Checking for %s\n", filename); if (Fs_Exists(filename)) { // it exists, no need to download return true; } Com_Debug("Attempting to download %s\n", filename); strncpy(cls.download.name, filename, sizeof(cls.download.name)); // udp downloads to a temp name, and only renames when done StripExtension(cls.download.name, cls.download.tempname); g_strlcat(cls.download.tempname, ".tmp", sizeof(cls.download.tempname)); // attempt an http download if available if (cls.download_url[0] && Cl_HttpDownload()) return false; // check to see if we already have a tmp for this file, if so, try to resume // open the file if not opened yet if (Fs_Exists(cls.download.tempname)) { // a temp file exists, resume download int64_t len = Fs_Load(cls.download.tempname, NULL); if ((cls.download.file = Fs_OpenAppend(cls.download.tempname))) { if (Fs_Seek(cls.download.file, len - 1)) { // give the server the offset to start the download Com_Debug("Resuming %s...\n", cls.download.name); g_snprintf(cmd, sizeof(cmd), "download %s %u", cls.download.name, (uint32_t) len); Net_WriteByte(&cls.net_chan.message, CL_CMD_STRING); Net_WriteString(&cls.net_chan.message, cmd); return false; } } } // or start if from the beginning Com_Debug("Downloading %s...\n", cls.download.name); g_snprintf(cmd, sizeof(cmd), "download %s", cls.download.name); Net_WriteByte(&cls.net_chan.message, CL_CMD_STRING); Net_WriteString(&cls.net_chan.message, cmd); return false; }
bool FCajunMaster::SpawnBot (const char *name, int color) { //COLORS static const char colors[11][17] = { "\\color\\40 cf 00", //0 = Green "\\color\\b0 b0 b0", //1 = Gray "\\color\\50 50 60", //2 = Indigo "\\color\\8f 00 00", //3 = Deep Red "\\color\\ff ff ff", //4 = White "\\color\\ff af 3f", //5 = Bright Brown "\\color\\bf 00 00", //6 = Red "\\color\\00 00 ff", //7 = Blue "\\color\\00 00 7f", //8 = Dark Blue "\\color\\ff ff 00", //9 = Yellow "\\color\\cf df 90" //10 = Bleached Bone }; botinfo_t *thebot = botinfo; int botshift = 0; if (name) { // Check if exist or already in the game. while (thebot && stricmp (name, thebot->name)) { botshift++; thebot = thebot->next; } if (thebot == NULL) { Printf ("couldn't find %s in %s\n", name, BOTFILENAME); return false; } else if (thebot->inuse == BOTINUSE_Waiting) { return false; } else if (thebot->inuse == BOTINUSE_Yes) { Printf ("%s is already in the thick\n", name); return false; } } else { //Spawn a random bot from bots.cfg if no name given. TArray<botinfo_t *> BotInfoAvailable; while (thebot) { if (thebot->inuse == BOTINUSE_No) BotInfoAvailable.Push (thebot); thebot = thebot->next; } if (BotInfoAvailable.Size () == 0) { Printf ("Couldn't spawn bot; no bot left in %s\n", BOTFILENAME); return false; } thebot = BotInfoAvailable[pr_botspawn() % BotInfoAvailable.Size ()]; botinfo_t *thebot2 = botinfo; while (thebot2) { if (thebot == thebot2) break; botshift++; thebot2 = thebot2->next; } } thebot->inuse = BOTINUSE_Waiting; Net_WriteByte (DEM_ADDBOT); Net_WriteByte (botshift); { //Set color. char concat[512]; strcpy (concat, thebot->info); if (color == NOCOLOR && bot_next_color < NOCOLOR && bot_next_color >= 0) { strcat (concat, colors[bot_next_color]); } if (TeamLibrary.IsValidTeam (thebot->lastteam)) { // Keep the bot on the same team when switching levels mysnprintf (concat + strlen(concat), countof(concat) - strlen(concat), "\\team\\%d\n", thebot->lastteam); } Net_WriteString (concat); } Net_WriteByte(thebot->skill.aiming); Net_WriteByte(thebot->skill.perfection); Net_WriteByte(thebot->skill.reaction); Net_WriteByte(thebot->skill.isp); return true; }
bool FCajunMaster::SpawnBot (const char *name, int color) { int playernumber; //COLORS static const char colors[11][17] = { "\\color\\40 cf 00", //0 = Green "\\color\\b0 b0 b0", //1 = Gray "\\color\\50 50 60", //2 = Indigo "\\color\\8f 00 00", //3 = Deep Red "\\color\\ff ff ff", //4 = White "\\color\\ff af 3f", //5 = Bright Brown "\\color\\bf 00 00", //6 = Red "\\color\\00 00 ff", //7 = Blue "\\color\\00 00 7f", //8 = Dark Blue "\\color\\ff ff 00", //9 = Yellow "\\color\\cf df 90" //10 = Bleached Bone }; for (playernumber = 0; playernumber < MAXPLAYERS; playernumber++) { if (!playeringame[playernumber] && !waitingforspawn[playernumber]) { break; } } if (playernumber == MAXPLAYERS) { Printf ("The maximum of %d players/bots has been reached\n", MAXPLAYERS); return false; } botinfo_t *thebot; if (name) { thebot = botinfo; // Check if exist or already in the game. while (thebot && stricmp (name, thebot->name)) thebot = thebot->next; if (thebot == NULL) { Printf ("couldn't find %s in %s\n", name, BOTFILENAME); return false; } else if (thebot->inuse) { Printf ("%s is already in the thick\n", name); return false; } } else if (botnum < loaded_bots) { bool vacant = false; //Spawn a random bot from bots.cfg if no name given. while (!vacant) { int rnum = (pr_botspawn() % loaded_bots); thebot = botinfo; while (rnum) --rnum, thebot = thebot->next; if (!thebot->inuse) vacant = true; } } else { Printf ("Couldn't spawn bot; no bot left in %s\n", BOTFILENAME); return false; } waitingforspawn[playernumber] = true; Net_WriteByte (DEM_ADDBOT); Net_WriteByte (playernumber); { //Set color. char concat[512]; strcpy (concat, thebot->info); if (color == NOCOLOR && bot_next_color < NOCOLOR && bot_next_color >= 0) { strcat (concat, colors[bot_next_color]); } if (TeamLibrary.IsValidTeam (thebot->lastteam)) { // Keep the bot on the same team when switching levels mysnprintf (concat + strlen(concat), countof(concat) - strlen(concat), "\\team\\%d\n", thebot->lastteam); } Net_WriteString (concat); } players[playernumber].skill = thebot->skill; thebot->inuse = true; //Increment this. botnum++; return true; }