2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-01-07 12:35:33 +03:00
rehlds/rehlds/engine/host_cmd.cpp
s1lentq 2a24337eee Cut of nicknames '+' if next there is something digit or alphanumeric character.
Added prefix Q_* for functions strlen/strcmp/strpcy/memset/memcpy/memmove etc.
Added for solution configuration (Debug Swds Play/Release Swds Play) the path to libacof32.lib in linker.
2015-10-27 21:14:08 +06:00

3131 lines
83 KiB
C++

/*
*
* This program 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 2 of the License, or (at
* your option) any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
/* <3d3ff> ../engine/host_cmd.c:4378 */
typedef int(*SV_BLENDING_INTERFACE_FUNC)(int, struct sv_blending_interface_s **, struct server_studio_api_s *, float *, float *);
vec3_t r_origin;
double cpuPercent;
int32 startTime;
int current_skill;
CareerStateType g_careerState;
int gHostSpawnCount;
//qboolean noclip_anglehack;
qboolean g_bMajorMapChange;
int g_iQuitCommandIssued;
char *g_pPostRestartCmdLineArgs;
/*
* Globals initialization
*/
#ifndef HOOK_ENGINE
int r_dointerp = 1;
SV_SAVEGAMECOMMENT_FUNC g_pSaveGameCommentFunc = &Host_SavegameComment;
cvar_t voice_recordtofile = { "voice_recordtofile", "0", 0, 0.0f, NULL };
cvar_t voice_inputfromfile = { "voice_inputfromfile", "0", 0, 0.0f, NULL };
cvar_t gHostMap = { "HostMap", "C1A0", 0, 0.0f, NULL };
TITLECOMMENT gTitleComments[] =
{
{ "T0A0", "#T0A0TITLE" },
{ "C0A0", "#C0A0TITLE" },
{ "C1A0", "#C0A1TITLE" },
{ "C1A1", "#C1A1TITLE" },
{ "C1A2", "#C1A2TITLE" },
{ "C1A3", "#C1A3TITLE" },
{ "C1A4", "#C1A4TITLE" },
{ "C2A1", "#C2A1TITLE" },
{ "C2A2", "#C2A2TITLE" },
{ "C2A3", "#C2A3TITLE" },
{ "C2A4D", "#C2A4TITLE2" },
{ "C2A4E", "#C2A4TITLE2" },
{ "C2A4F", "#C2A4TITLE2" },
{ "C2A4G", "#C2A4TITLE2" },
{ "C2A4", "#C2A4TITLE1" },
{ "C2A5", "#C2A5TITLE" },
{ "C3A1", "#C3A1TITLE" },
{ "C3A2", "#C3A2TITLE" },
{ "C4A1A", "#C4A1ATITLE" },
{ "C4A1B", "#C4A1ATITLE" },
{ "C4A1C", "#C4A1ATITLE" },
{ "C4A1D", "#C4A1ATITLE" },
{ "C4A1E", "#C4A1ATITLE" },
{ "C4A1", "#C4A1TITLE" },
{ "C4A2", "#C4A2TITLE" },
{ "C4A3", "#C4A3TITLE" },
{ "C5A1", "#C5TITLE" },
{ "OFBOOT", "#OF_BOOT0TITLE" },
{ "OF0A", "#OF1A1TITLE" },
{ "OF1A1", "#OF1A3TITLE" },
{ "OF1A2", "#OF1A3TITLE" },
{ "OF1A3", "#OF1A3TITLE" },
{ "OF1A4", "#OF1A3TITLE" },
{ "OF1A", "#OF1A5TITLE" },
{ "OF2A1", "#OF2A1TITLE" },
{ "OF2A2", "#OF2A1TITLE" },
{ "OF2A3", "#OF2A1TITLE" },
{ "OF2A", "#OF2A4TITLE" },
{ "OF3A1", "#OF3A1TITLE" },
{ "OF3A2", "#OF3A1TITLE" },
{ "OF3A", "#OF3A3TITLE" },
{ "OF4A1", "#OF4A1TITLE" },
{ "OF4A2", "#OF4A1TITLE" },
{ "OF4A3", "#OF4A1TITLE" },
{ "OF4A", "#OF4A4TITLE" },
{ "OF5A", "#OF5A1TITLE" },
{ "OF6A1", "#OF6A1TITLE" },
{ "OF6A2", "#OF6A1TITLE" },
{ "OF6A3", "#OF6A1TITLE" },
{ "OF6A4b", "#OF6A4TITLE" },
{ "OF6A4", "#OF6A1TITLE" },
{ "OF6A5", "#OF6A4TITLE" },
{ "OF6A", "#OF6A4TITLE" },
{ "OF7A", "#OF7A0TITLE" },
{ "ba_tram", "#BA_TRAMTITLE" },
{ "ba_security", "#BA_SECURITYTITLE" },
{ "ba_main", "#BA_SECURITYTITLE" },
{ "ba_elevator", "#BA_SECURITYTITLE" },
{ "ba_canal", "#BA_CANALSTITLE" },
{ "ba_yard", "#BA_YARDTITLE" },
{ "ba_xen", "#BA_XENTITLE" },
{ "ba_hazard", "#BA_HAZARD" },
{ "ba_power", "#BA_POWERTITLE" },
{ "ba_teleport1", "#BA_YARDTITLE" },
{ "ba_teleport", "#BA_TELEPORTTITLE" },
{ "ba_outro", "#BA_OUTRO" }
};
TYPEDESCRIPTION gGameHeaderDescription[] =
{
DEFINE_FIELD(GAME_HEADER, mapCount, FIELD_INTEGER),
DEFINE_ARRAY(GAME_HEADER, mapName, FIELD_CHARACTER, 32),
DEFINE_ARRAY(GAME_HEADER, comment, FIELD_CHARACTER, 80),
};
TYPEDESCRIPTION gSaveHeaderDescription[] =
{
DEFINE_FIELD(SAVE_HEADER, skillLevel, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, entityCount, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, connectionCount, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, lightStyleCount, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, time, FIELD_TIME),
DEFINE_ARRAY(SAVE_HEADER, mapName, FIELD_CHARACTER, 32),
DEFINE_ARRAY(SAVE_HEADER, skyName, FIELD_CHARACTER, 32),
DEFINE_FIELD(SAVE_HEADER, skyColor_r, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, skyColor_g, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, skyColor_b, FIELD_INTEGER),
DEFINE_FIELD(SAVE_HEADER, skyVec_x, FIELD_FLOAT),
DEFINE_FIELD(SAVE_HEADER, skyVec_y, FIELD_FLOAT),
DEFINE_FIELD(SAVE_HEADER, skyVec_z, FIELD_FLOAT),
};
TYPEDESCRIPTION gAdjacencyDescription[] =
{
DEFINE_ARRAY(LEVELLIST, mapName, FIELD_CHARACTER, 32),
DEFINE_ARRAY(LEVELLIST, landmarkName, FIELD_CHARACTER, 32),
DEFINE_FIELD(LEVELLIST, pentLandmark, FIELD_EDICT),
DEFINE_FIELD(LEVELLIST, vecLandmarkOrigin, FIELD_VECTOR),
};
TYPEDESCRIPTION gEntityTableDescription[] =
{
DEFINE_FIELD(ENTITYTABLE, id, FIELD_INTEGER),
DEFINE_FIELD(ENTITYTABLE, location, FIELD_INTEGER),
DEFINE_FIELD(ENTITYTABLE, size, FIELD_INTEGER),
DEFINE_FIELD(ENTITYTABLE, flags, FIELD_INTEGER),
DEFINE_FIELD(ENTITYTABLE, classname, FIELD_STRING),
};
TYPEDESCRIPTION gLightstyleDescription[] =
{
DEFINE_FIELD(SAVELIGHTSTYLE, index, FIELD_INTEGER),
DEFINE_ARRAY(SAVELIGHTSTYLE, style, FIELD_CHARACTER, MAX_LIGHTSTYLES),
};
#else //HOOK_ENGINE
int r_dointerp;
SV_SAVEGAMECOMMENT_FUNC g_pSaveGameCommentFunc;
cvar_t voice_recordtofile;
cvar_t voice_inputfromfile;
cvar_t gHostMap;
TITLECOMMENT gTitleComments[66];
TYPEDESCRIPTION gGameHeaderDescription[3];
TYPEDESCRIPTION gSaveHeaderDescription[13];
TYPEDESCRIPTION gAdjacencyDescription[4];
TYPEDESCRIPTION gEntityTableDescription[5];
TYPEDESCRIPTION gLightstyleDescription[2];
#endif //HOOK_ENGINE
/* <3e21d> ../engine/host_cmd.c:192 */
void SV_GetPlayerHulls(void)
{
int i;
//int iResult;//unused?
for (i = 0; i < 4; i++)
{
if (!gEntityInterface.pfnGetHullBounds(i, player_mins[i], player_maxs[i]))
break;
}
}
/* <3e298> ../engine/host_cmd.c:216 */
void Host_InitializeGameDLL(void)
{
Cbuf_Execute();
NET_Config(g_psvs.maxclients > 1);
if (g_psvs.dll_initialized)
{
Con_DPrintf("Sys_InitializeGameDLL called twice, skipping second call\n");
return;
}
g_psvs.dll_initialized = TRUE;
LoadEntityDLLs(host_parms.basedir);
gEntityInterface.pfnGameInit();
gEntityInterface.pfnPM_Init(&g_svmove);
gEntityInterface.pfnRegisterEncoders();
SV_InitEncoders();
SV_GetPlayerHulls();
SV_CheckBlendingInterface();
SV_CheckSaveGameCommentInterface();
Cbuf_Execute();
}
/* <3d608> ../engine/host_cmd.c:271 */
void Host_Motd_f(void)
{
int length;
FileHandle_t pFile;
char *pFileList;
char *next;
pFileList = motdfile.string;
if (*pFileList == '/' || Q_strstr(pFileList, ":") || Q_strstr(pFileList, "..") || Q_strstr(pFileList, "\\"))
{
Con_Printf("Unable to open %s (contains illegal characters)\n", pFileList);
return;
}
pFile = FS_Open(pFileList, "rb");
if (!pFile)
{
Con_Printf("Unable to open %s\n", pFileList);
return;
}
length = FS_Size(pFile);
if (length > 0)
{
char* buf = (char *)Mem_Malloc(length + 1);
if (buf)
{
FS_Read(buf, length, 1, pFile);
buf[length] = 0;
char* now = buf;
Con_Printf("motd:");
next = Q_strchr(now, '\n');
while (next != NULL)
{
*next = 0;
Con_Printf("%s\n", now);
now = next + 1;
next = Q_strchr(now, '\n');
}
Con_Printf("%s\n", now);
Mem_Free(buf);
}
}
FS_Close(pFile);
}
/* <3d5d4> ../engine/host_cmd.c:335 */
void Host_Motd_Write_f(void)
{
char newFile[2048];
unsigned int i;
FileHandle_t pFile;
if (!g_psv.active || cmd_source != src_command || g_pcls.state)
return;
if (!IsSafeFileToDownload(motdfile.string) || !Q_strstr(motdfile.string, ".txt"))
{
Con_Printf("Invalid motdfile name (%s)\n", motdfile.string);
return;
}
pFile = FS_Open(motdfile.string, "wb+");
if (!pFile)
{
Con_Printf("Unable to open %s\n", motdfile.string);
return;
}
Q_strncpy(newFile, Cmd_Args(), ARRAYSIZE(newFile));
#ifdef REHLDS_FIXES
newFile[ARRAYSIZE(newFile) - 1] = 0;
#endif // REHLDS_FIXES
for (i = 0; i < Q_strlen(newFile); i++)
{
if (newFile[i] == '\\' && newFile[i + 1] == 'n')
{
newFile[i] = '\n';
Q_strncpy(&newFile[i + 1], &newFile[i + 2], min(sizeof(newFile) - 1, Q_strlen(newFile) + 1));
newFile[sizeof(newFile) - 1] = 0;
}
}
FS_Write(newFile, Q_strlen(newFile), 1, pFile);
FS_Close(pFile);
Con_Printf("Done.\n");
}
/* <3e382> ../engine/host_cmd.c:395 */
int Host_GetStartTime(void)
{
return startTime;
}
/* <3e39a> ../engine/host_cmd.c:405 */
void Host_UpdateStats(void)
{
uint32 runticks = 0;
uint32 cputicks = 0;
static float last = 0.0f;
static float lastAvg = 0.0f;
static uint64 lastcputicks = 0;
static uint64 lastrunticks = 0;
#ifdef _WIN32
struct _FILETIME ExitTime;
struct _FILETIME UserTime;
struct _FILETIME KernelTime;
struct _FILETIME CreationTime;
struct _FILETIME SystemTimeAsFileTime;
if (!startTime)
startTime = Sys_FloatTime();
if (last + 1.0 < Sys_FloatTime())
{
GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime);
GetSystemTimeAsFileTime(&SystemTimeAsFileTime);
//CRehldsPlatformHolder::get()->GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime);
//CRehldsPlatformHolder::get()->GetSystemTimeAsFileTime(&SystemTimeAsFileTime);
if (!lastcputicks)
{
cputicks = CreationTime.dwLowDateTime;
runticks = CreationTime.dwHighDateTime;
lastcputicks = FILETIME_TO_QWORD(CreationTime);
}
else
{
cputicks = (uint32)(lastcputicks & 0xFFFFFFFF);
runticks = (uint32)(lastcputicks >> 32);
}
cpuPercent =
(FILETIME_TO_QWORD(UserTime) + FILETIME_TO_QWORD(KernelTime) - lastrunticks)
/ (FILETIME_TO_QWORD(SystemTimeAsFileTime)
- (double)FILETIME_TO_PAIR(runticks, cputicks));
if (lastAvg + 5.0f < Sys_FloatTime())
{
lastcputicks = FILETIME_TO_QWORD(SystemTimeAsFileTime);
lastrunticks = FILETIME_TO_QWORD(UserTime) + FILETIME_TO_QWORD(KernelTime);
lastAvg = last;
}
last = Sys_FloatTime();
}
#else // _WIN32
FILE *pFile;
int32 dummy;
int32 ctime;
int32 stime;
int32 start_time;
char statFile[4096];
struct sysinfo infos;
if (!startTime)
startTime = Sys_FloatTime();
if (Sys_FloatTime() > last + 1.0f)
{
time(NULL);
pid_t pid = getpid();
Q_snprintf(statFile, sizeof(statFile), "/proc/%i/stat", pid);
pFile = fopen(statFile, "rt");
if (!pFile)
{
last = Sys_FloatTime();
return;
}
sysinfo(&infos);
fscanf(pFile, "%d %s %c %d %d %d %d %d %lu %lu \t\t\t%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu \t\t\t%lu %ld %lu %lu %lu %lu %lu %lu %lu %lu \t\t\t%lu %lu %lu %lu %lu %lu",
&dummy,
statFile,
&dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
&ctime,
&stime,
&dummy, &dummy, &dummy, &dummy, &dummy,
&start_time,
&dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
&dummy, &dummy, &dummy, &dummy, &dummy,&dummy,&dummy,&dummy
);
fclose(pFile);
runticks = 100 * infos.uptime - start_time;
cputicks = ctime + stime;
if (!lastcputicks)
lastcputicks = cputicks;
if (lastrunticks)
cpuPercent = (double)(cputicks - lastcputicks) / (double)(runticks - lastrunticks);
else
lastrunticks = runticks;
if (lastAvg + 5.0f < Sys_FloatTime())
{
lastcputicks = cputicks;
lastrunticks = runticks;
lastAvg = Sys_FloatTime();
}
if (cpuPercent > 0.999)
cpuPercent = 0.999;
else if (cpuPercent < 0.0)
cpuPercent = 0.0;
last = Sys_FloatTime();
}
#endif // _WIN32
}
/* <3da03> ../engine/host_cmd.c:580 */
void GetStatsString(char *buf, int bufSize)
{
long double avgOut = 0.0;
long double avgIn = 0.0;
int players = 0;
for (int i = 0; i < g_psvs.maxclients; i++)
{
host_client = &g_psvs.clients[i];
if (!host_client->active && !host_client->connected && !host_client->spawned || host_client->fakeclient)
continue;
players++;
avgIn = avgIn + host_client->netchan.flow[FLOW_INCOMING].avgkbytespersec;
avgOut = avgOut + host_client->netchan.flow[FLOW_OUTGOING].avgkbytespersec;
}
Q_snprintf(buf, bufSize - 1, "%5.2f %5.2f %5.2f %7i %5i %7.2f %7i",
(float)(100.0 * cpuPercent),
(float)avgIn,
(float)avgOut,
(int)floor(Sys_FloatTime() - startTime) / 60,
g_userid - 1,
(float)(1.0 / host_frametime),
players);
buf[bufSize - 1] = 0;
}
/* <3e059> ../engine/host_cmd.c:613 */
void Host_Stats_f(void)
{
char stats[512];
GetStatsString(stats, sizeof(stats));
Con_Printf("CPU In Out Uptime Users FPS Players\n%s\n", stats);
}
/* <3d5c9> ../engine/host_cmd.c:626 */
void Host_Quit_f(void)
{
if (Cmd_Argc() == 1)
{
giActive = DLL_CLOSE;
g_iQuitCommandIssued = 1;
if (g_pcls.state)
CL_Disconnect();
Host_ShutdownServer(FALSE);
Sys_Quit();
}
else
{
giActive = DLL_PAUSED;
giStateInfo = 4;
}
}
/* <3d5be> ../engine/host_cmd.c:651 */
void Host_Quit_Restart_f(void)
{
giActive = DLL_RESTART;
giStateInfo = 4;
if (g_psv.active || (g_pcls.state == ca_active && g_pcls.trueaddress[0] && g_pPostRestartCmdLineArgs))
{
Q_strcat(g_pPostRestartCmdLineArgs, " +connect ");
Q_strcat(g_pPostRestartCmdLineArgs, g_pcls.servername);
}
else
{
if (g_psvs.maxclients == 1 && g_pcls.state == ca_active)
{
if (g_pPostRestartCmdLineArgs)
{
Cbuf_AddText("save quick\n");
Cbuf_Execute();
Q_strcat(g_pPostRestartCmdLineArgs, " +load quick");
}
}
}
}
/* <3e511> ../engine/host_cmd.c:700 */
void Host_Status_Printf(qboolean conprint, qboolean log, char *fmt, ...)
{
va_list argptr;
char string[4096];
char szfile[260];
va_start(argptr, fmt);
vsprintf(string, fmt, argptr);
va_end(argptr);
if (conprint)
Con_Printf("%s", string);
else SV_ClientPrintf("%s", string);
if (log)
{
Q_snprintf(szfile, sizeof(szfile), "%s", "status.log");
COM_Log(szfile, "%s", string);
}
}
/* <3e666> ../engine/host_cmd.c:735 */
void Host_Status_f(void)
{
client_t *client;
int seconds;
int minutes;
int hltv_slots = 0;
int hltv_specs = 0;
int hltv_delay = 0;
char *val;
int hours;
int j;
int nClients;
qboolean log = FALSE;
qboolean conprint = FALSE;
qboolean bIsSecure;
qboolean bWantsToBeSecure;
qboolean bConnectedToSteam3;
const char *pchConnectionString = "";
const char *pchSteamUniverse = "";
char szfile[260];
if (cmd_source == src_command)
{
conprint = TRUE;
if (!g_psv.active)
{
Cmd_ForwardToServer();
return;
}
}
if (Cmd_Argc() == 2 && !Q_stricmp(Cmd_Argv(1), "log"))
{
log = TRUE;
Q_snprintf(szfile, sizeof(szfile), "%s", "status.log");
_unlink(szfile);
}
Host_Status_Printf(conprint, log, "hostname: %s\n", Cvar_VariableString("hostname"));
bIsSecure = Steam_GSBSecure();
bWantsToBeSecure = Steam_GSBSecurePreference();
bConnectedToSteam3 = Steam_GSBLoggedOn();
if (!bIsSecure && bWantsToBeSecure)
{
pchConnectionString = "(secure mode enabled, connected to Steam3)";
if (!bConnectedToSteam3)
{
pchConnectionString = "(secure mode enabled, disconnected from Steam3)";
}
}
if (g_psv.active)
{
pchSteamUniverse = Steam_GetGSUniverse();
}
val = "insecure";
if (bIsSecure)
val = "secure";
Host_Status_Printf(conprint, log, "version : %i/%s %d %s %s%s (%d)\n", PROTOCOL_VERSION, gpszVersionString, build_number(), val, pchConnectionString, pchSteamUniverse, GetGameAppID());
if (!noip)
{
Host_Status_Printf(conprint, log, "tcp/ip : %s\n", NET_AdrToString(net_local_adr));
}
#ifdef _WIN32
if (!noipx)
{
Host_Status_Printf(conprint, log, "ipx : %s\n", NET_AdrToString(net_local_ipx_adr));
}
#endif // _WIN32
Host_Status_Printf(conprint, log, "map : %s at: %d x, %d y, %d z\n", g_psv.name, r_origin[0], r_origin[1], r_origin[2]);
SV_CountPlayers(&nClients);
Host_Status_Printf(conprint, log, "players : %i active (%i max)\n\n", nClients, g_psvs.maxclients);
Host_Status_Printf(conprint, log, "# name userid uniqueid frag time ping loss adr\n");
int count = 1;
client = g_psvs.clients;
for (j = 0; j < g_psvs.maxclients; j++, client++)
{
if (!client->active)
{
continue;
}
hours = 0;
seconds = realtime - client->netchan.connect_time;
minutes = seconds / 60;
if (minutes)
{
seconds %= 60;
hours = minutes / 60;
if (hours)
minutes %= 60;
}
if (!client->fakeclient)
val = SV_GetClientIDString(client);
else val = "BOT";
Host_Status_Printf(conprint, log, "#%2i %8s %i %s", count++, va("\"%s\"", client->name), client->userid, val);
if (client->proxy)
{
const char *userInfo = Info_ValueForKey(client->userinfo, "hspecs");
if (Q_strlen(userInfo))
hltv_specs = Q_atoi(userInfo);
userInfo = Info_ValueForKey(client->userinfo, "hslots");
if (Q_strlen(userInfo))
hltv_slots = Q_atoi(userInfo);
userInfo = Info_ValueForKey(client->userinfo, "hdelay");
if (Q_strlen(userInfo))
hltv_delay = Q_atoi(userInfo);
Host_Status_Printf(conprint, log, " hltv:%u/%u delay:%u", hltv_specs, hltv_slots, hltv_delay);
}
else
Host_Status_Printf(conprint, log, " %3i", (int)client->edict->v.frags);
if (hours)
Host_Status_Printf(conprint, log, " %2i:%02i:%02i", hours, minutes, seconds);
else Host_Status_Printf(conprint, log, " %02i:%02i", minutes, seconds);
Host_Status_Printf(conprint, log, " %4i %3i", SV_CalcPing(client), (int)client->packet_loss);
if ((conprint || client->proxy) && client->netchan.remote_address.type == NA_IP)
{
Host_Status_Printf(conprint, log, " %s\n", NET_AdrToString(client->netchan.remote_address));
}
else Host_Status_Printf(conprint, log, "\n");
}
Host_Status_Printf(conprint, log, "%i users\n", nClients);
}
/* <3e594> ../engine/host_cmd.c:923 */
void Host_Status_Formatted_f(void)
{
client_t *client;
int seconds;
int minutes;
int hours;
int j;
int nClients;
qboolean log = FALSE;
qboolean conprint = FALSE;
qboolean bIsSecure;
char sz[32];
char szfile[MAX_PATH];
char *szIDString;
if (cmd_source == src_command)
{
conprint = TRUE;
if (!g_psv.active)
{
Cmd_ForwardToServer();
return;
}
}
if (Cmd_Argc() == 2 && !Q_stricmp(Cmd_Argv(1), "log"))
{
Q_snprintf(szfile, sizeof(szfile), "%s", "status.log");
_unlink(szfile);
log = TRUE;
}
bIsSecure = Steam_GSBSecure();
Host_Status_Printf(conprint, log, "hostname: %s\n", Cvar_VariableString("hostname"));
char *szSecure = "insecure";
if (bIsSecure)
szSecure = "secure";
Host_Status_Printf(conprint, log, "version : %i/%s %d %s\n", PROTOCOL_VERSION, gpszVersionString, build_number(), szSecure);
if (!noip)
{
Host_Status_Printf(conprint, log, "tcp/ip : %s\n", NET_AdrToString(net_local_adr));
}
#ifdef _WIN32
if (!noipx)
{
Host_Status_Printf(conprint, log, "ipx : %s\n", NET_AdrToString(net_local_ipx_adr));
}
#endif // _WIN32
Host_Status_Printf(conprint, log, "map : %s at: %d x, %d y, %d z\n", g_psv.name, r_origin[0], r_origin[1], r_origin[2]);
SV_CountPlayers(&nClients);
Host_Status_Printf(conprint, log, "players : %i active (%i max)\n\n", nClients, g_psvs.maxclients);
Host_Status_Printf(conprint, log, "%-2.2s\t%-9.9s\t%-7.7s\t%-20.20s\t%-4.4s\t%-8.8s\t%-4.4s\t%-4.4s\t%-21.21s\n","# ","name","userid ","uniqueid ","frag","time ","ping","loss","adr");
int count = 1;
char *szRemoteAddr;
client = g_psvs.clients;
for (j = 0; j < g_psvs.maxclients; j++, client++)
{
if (!client->active)
{
continue;
}
seconds = realtime - client->netchan.connect_time;
minutes = seconds / 60;
hours = minutes / 60;
if (minutes && hours)
Q_snprintf(sz, sizeof(sz), "%-2i:%02i:%02i", hours, minutes % 60, seconds % 60);
else
Q_snprintf(sz, sizeof(sz), "%02i:%02i", minutes, seconds % 60);
if (conprint)
szRemoteAddr = NET_AdrToString(client->netchan.remote_address);
else szRemoteAddr = "";
#ifdef REHLDS_FIXES
//TODO: I think it would be better if do the formatting for fakeclient as in Host_Status_f (in the original it there is no)
if (client->fakeclient)
szIDString = "BOT";
else
#endif // REHLDS_FIXES
szIDString = SV_GetClientIDString(client);
Host_Status_Printf(conprint, log, "%-2.2s\t%-9.9s\t%-7.7s\t%-20.20s\t%-4.4s\t%-8.8s\t%-4.4s\t%-4.4s\t%-21.21s\n",
va("%-2i", count++),va("\"%s\"", client->name),va("%-7i", client->userid),szIDString,
va("%-4i", (int)client->edict->v.frags),sz,va("%-4i", SV_CalcPing(client)),va("%-4i", (int)client->packet_loss),szRemoteAddr);
}
Host_Status_Printf(conprint, log, "%i users\n", nClients);
}
/* <3dc0c> ../engine/host_cmd.c:1219 */
void Host_Ping_f(void)
{
int i;
client_t *client;
if (cmd_source == src_command)
{
Cmd_ForwardToServer();
return;
}
SV_ClientPrintf("Client ping times:\n");
client = g_psvs.clients;
for (i = 0; i < g_psvs.maxclients; i++, client++)
{
if (client->active)
SV_ClientPrintf("%4i %s\n", SV_CalcPing(client), client->name);
}
}
/* <3fc89> ../engine/host_cmd.c:1249 */
void Host_Map(qboolean bIsDemo, char *mapstring, char *mapName, qboolean loadGame)
{
int i;
UserMsg *pMsg;
Host_ShutdownServer(FALSE);
key_dest = key_game;
SCR_BeginLoadingPlaque(FALSE);
if (!loadGame)
{
Host_ClearGameState();
SV_InactivateClients();
g_psvs.serverflags = 0;
}
Q_strncpy(g_pcls.mapstring, mapstring, sizeof(g_pcls.mapstring) - 1);
g_pcls.mapstring[sizeof(g_pcls.mapstring) - 1] = 0;
if (SV_SpawnServer(bIsDemo, mapName, NULL))
{
ContinueLoadingProgressBar("Server", 7, 0.0);
if (loadGame)
{
if (!LoadGamestate(mapName, 1))
SV_LoadEntities();
g_psv.paused = TRUE;
g_psv.loadgame = TRUE;
SV_ActivateServer(0);
}
else
{
SV_LoadEntities();
SV_ActivateServer(1);
if (!g_psv.active)
return;
if (g_pcls.state != ca_dedicated)
{
Q_strcpy(g_pcls.spawnparms, "");
for (i = 0; i < Cmd_Argc(); i++)
Q_strncat(g_pcls.spawnparms, Cmd_Argv(i), sizeof(g_pcls.spawnparms) - Q_strlen(g_pcls.spawnparms) - 1);
}
}
if (sv_gpNewUserMsgs)
{
pMsg = sv_gpUserMsgs;
if (pMsg)
{
while (pMsg->next)
pMsg = pMsg->next;
pMsg->next = sv_gpNewUserMsgs;
}
else
sv_gpUserMsgs = sv_gpNewUserMsgs;
sv_gpNewUserMsgs = NULL;
}
if (g_pcls.state)
Cmd_ExecuteString("connect local", src_command);
}
}
/* <3ff7f> ../engine/host_cmd.c:1339 */
void Host_Map_f(void)
{
int i;
char mapstring[64];
char name[64];
CareerStateType careerState = g_careerState;
if (cmd_source != src_command)
{
g_careerState = CAREER_NONE;
return;
}
if (Cmd_Argc() > 1 && Q_strlen(Cmd_Args()) > 54)
{
g_careerState = CAREER_NONE;
Con_Printf("map change failed: command string is too long.\n");
return;
}
if (Cmd_Argc() < 2)
{
g_careerState = CAREER_NONE;
Con_Printf("map <levelname> : changes server to specified map\n");
return;
}
CL_Disconnect();
//TODO: what it? why is this?
if (careerState == CAREER_LOADING)
g_careerState = CAREER_LOADING;
if (COM_CheckParm("-steam") && PF_IsDedicatedServer())
g_bMajorMapChange = TRUE;
FS_LogLevelLoadStarted("Map_Common");
mapstring[0] = 0;
for (i = 0; i < Cmd_Argc(); i++)
{
Q_strncat(mapstring, Cmd_Argv(i), 62 - Q_strlen(mapstring));
Q_strncat(mapstring, " ", 62 - Q_strlen(mapstring));
}
Q_strcat(mapstring, "\n");
Q_strncpy(name, Cmd_Argv(1), sizeof(name) - 1);
name[sizeof(name) - 1] = 0;
if (!g_psvs.dll_initialized)
Host_InitializeGameDLL();
int iLen = Q_strlen(name);
if (iLen > 4 && !Q_stricmp(&name[iLen - 4], ".bsp"))
name[iLen - 4] = 0;
FS_LogLevelLoadStarted(name);
VGuiWrap2_LoadingStarted("level", name);
SCR_UpdateScreen();
SCR_UpdateScreen();
if (!PF_IsMapValid_I(name))
{
Con_Printf("map change failed: '%s' not found on server.\n", name);
if (COM_CheckParm("-steam"))
{
if (PF_IsDedicatedServer())
{
g_bMajorMapChange = FALSE;
Sys_Printf("\n");
}
}
return;
}
StartLoadingProgressBar("Server", 24);
SetLoadingProgressBarStatusText("#GameUI_StartingServer");
ContinueLoadingProgressBar("Server", 1, 0.0);
Cvar_Set("HostMap", name);
Host_Map(FALSE, mapstring, name, FALSE);
if (COM_CheckParm("-steam") && PF_IsDedicatedServer())
{
g_bMajorMapChange = FALSE;
Sys_Printf("\n");
}
ContinueLoadingProgressBar("Server", 11, 0.0);
NotifyDedicatedServerUI("UpdateMap");
if (g_careerState == CAREER_LOADING)
{
g_careerState = CAREER_PLAYING;
SetCareerAudioState(1);
}
else
SetCareerAudioState(0);
}
/* <4004e> ../engine/host_cmd.c:1475 */
void Host_Career_f(void)
{
if (cmd_source == src_command)
{
g_careerState = CAREER_LOADING;
Host_Map_f();
}
}
/* <3d5a2> ../engine/host_cmd.c:1493 */
void Host_Maps_f(void)
{
char *pszSubString;
if (Cmd_Argc() != 2)
{
Con_Printf("Usage: maps <substring>\nmaps * for full listing\n");
return;
}
pszSubString = (char *)Cmd_Argv(1);
if (pszSubString && *pszSubString)
{
if (*pszSubString == '*')
pszSubString = NULL;
COM_ListMaps(pszSubString);
}
}
/* <3d56e> ../engine/host_cmd.c:1521 */
void Host_Changelevel_f(void)
{
char _level[64];
char _startspot[64];
char *level = NULL;
char *startspot = NULL;
if (Cmd_Argc() < 2)
{
Con_Printf("changelevel <levelname> : continue game on a new level\n");
return;
}
if (!g_psv.active || g_pcls.demoplayback)
{
Con_Printf("Only the server may changelevel\n");
return;
}
level = (char *)Cmd_Argv(1);
if (!PF_IsMapValid_I(level))
{
Con_Printf("changelevel failed: '%s' not found on server.\n", level);
return;
}
Q_strncpy(_level, level, 63);
_level[63] = 0;
if (Cmd_Argc() != 2)
{
startspot = &_startspot[0];
Q_strncpy(_startspot, Cmd_Argv(2), 63);
_startspot[63] = 0;
}
else
_startspot[0] = 0;
SCR_BeginLoadingPlaque(FALSE);
S_StopAllSounds(1);
SV_InactivateClients();
SV_ServerShutdown();
SV_SpawnServer(FALSE, _level, startspot);
SV_LoadEntities();
SV_ActivateServer(1);
}
/* <3e7c9> ../engine/host_cmd.c:1581 */
const char *Host_FindRecentSave(char *pNameBuf)
{
const char *findfn;
char basefilename[MAX_PATH];
int found;
#ifdef REHLDS_FIXES
int32 newest = 0;
#else
int32 newest;
#endif
int32 ft;
char szPath[MAX_PATH];
Q_sprintf(pNameBuf, "%s*.sav", Host_SaveGameDirectory());
Q_snprintf(szPath, sizeof(szPath), "%s", Host_SaveGameDirectory());
found = 0;
findfn = Sys_FindFirst(pNameBuf,basefilename);
while (findfn != NULL)
{
if (Q_strlen(findfn) && Q_stricmp(findfn, "HLSave.sav"))
{
Q_snprintf(szPath, sizeof(szPath), "%s%s", Host_SaveGameDirectory(), findfn);
ft = FS_GetFileTime(szPath);
if (ft > 0 && (!found || newest < ft))
{
found = 1;
newest = ft;
Q_strcpy(pNameBuf, findfn);
}
}
findfn = Sys_FindNext(basefilename);
}
Sys_FindClose();
return found != 0 ? pNameBuf : NULL;
}
/* <3fc40> ../engine/host_cmd.c:1637 */
void Host_Restart_f(void)
{
char name[MAX_PATH];
if (g_pcls.demoplayback || !g_psv.active || cmd_source != src_command)
return;
if (g_pcls.state)
g_pcls.state = ca_disconnected;
Host_ClearGameState();
SV_InactivateClients();
Q_strncpy(name, g_psv.name, sizeof(name) - 1);
name[sizeof(name) - 1] = 0;
SV_ServerShutdown();
SV_SpawnServer(FALSE, name, NULL);
SV_LoadEntities();
SV_ActivateServer(1);
}
/* <3d784> ../engine/host_cmd.c:1681 */
void Host_Reload_f(void)
{
const char *pSaveName;
char name[MAX_PATH];
if (g_pcls.demoplayback || !g_psv.active || cmd_source != src_command)
return;
Host_ClearGameState();
SV_InactivateClients();
SV_ServerShutdown();
pSaveName = Host_FindRecentSave(name);
if (!pSaveName || !Host_Load(pSaveName))
{
SV_SpawnServer(FALSE, gHostMap.string, NULL);
SV_LoadEntities();
SV_ActivateServer(1);
}
}
/* <3d552> ../engine/host_cmd.c:1730 */
void Host_Reconnect_f(void)
{
char cmdString[128];
if (g_pcls.state < ca_connected)
return;
if (g_pcls.passive)
{
Q_snprintf(cmdString, sizeof(cmdString), "listen %s\n", NET_AdrToString(g_pcls.connect_stream));
Cbuf_AddText(cmdString);
return;
}
SCR_BeginLoadingPlaque(FALSE);
g_pcls.signon = 0;
g_pcls.state = ca_connected;
sys_timescale.value = 1.0f;
Netchan_Clear(&g_pcls.netchan);
SZ_Clear(&g_pcls.netchan.message);
MSG_WriteChar(&g_pcls.netchan.message, clc_stringcmd);
MSG_WriteString(&g_pcls.netchan.message, "new");
}
/* <3e7a9> ../engine/host_cmd.c:1780 */
char *Host_SaveGameDirectory(void)
{
static char szDirectory[MAX_PATH];
Q_memset(szDirectory, 0, sizeof(szDirectory));
Q_snprintf(szDirectory, sizeof(szDirectory), "SAVE/");
return szDirectory;
}
/* <3dba5> ../engine/host_cmd.c:1877 */
void Host_SavegameComment(char *pszBuffer, int iSizeBuffer)
{
int i;
const char *pszName = NULL;
const char *pszMapName = (const char *)&pr_strings[gGlobalVariables.mapname];
for (i = 0; i < ARRAYSIZE(gTitleComments) && !pszName; i++)
{
if (!Q_strnicmp(pszMapName, gTitleComments[i].pBSPName, Q_strlen(gTitleComments[i].pBSPName)))
pszName = gTitleComments[i].pTitleName;
}
if (!pszName)
{
if (!pszMapName || !pszMapName[0])
{
pszName = pszMapName;
if (!Q_strlen(g_pcl.levelname))
pszName = g_pcl.levelname;
}
}
Q_strncpy(pszBuffer, pszName, iSizeBuffer - 1);
pszBuffer[iSizeBuffer - 1] = 0;
}
/* <3e8e9> ../engine/host_cmd.c:1909 */
void Host_SaveAgeList(const char *pName, int count)
{
char newName[MAX_PATH];
char oldName[MAX_PATH];
Q_snprintf(newName, sizeof(newName), "%s%s%02d.sav", Host_SaveGameDirectory(), pName, count);
COM_FixSlashes(newName);
FS_RemoveFile(newName, "GAMECONFIG");
while (count > 0)
{
if (count == 1)
Q_snprintf(oldName, sizeof(oldName), "%s%s.sav", Host_SaveGameDirectory(), pName);
else
Q_snprintf(oldName, sizeof(oldName), "%s%s%02d.sav", Host_SaveGameDirectory(), pName, count - 1);
COM_FixSlashes(oldName);
Q_snprintf(newName, sizeof(newName), "%s%s%02d.sav", Host_SaveGameDirectory(), pName, count);
COM_FixSlashes(newName);
FS_Rename(oldName, newName);
count--;
}
}
/* <3e9ba> ../engine/host_cmd.c:1938 */
int Host_ValidSave(void)
{
if (cmd_source != src_command)
return 0;
if (!g_psv.active)
{
Con_Printf("Not playing a local game.\n");
return 0;
}
if (g_psvs.maxclients != 1)
{
Con_Printf("Can't save multiplayer games.\n");
return 0;
}
if (g_pcls.state != ca_active || g_pcls.signon != 2)
{
Con_Printf("Can't save during transition.\n");
return 0;
}
if (g_pcl.intermission)
{
Con_Printf("Can't save in intermission.\n");
return 0;
}
if (g_psvs.clients->active && g_psvs.clients->edict->v.health <= 0.0)
{
Con_Printf("Can't savegame with a dead player\n");
return 0;
}
return 1;
}
/* <3da59> ../engine/host_cmd.c:1983 */
SAVERESTOREDATA *SaveInit(int size)
{
int i;
edict_t *pEdict;
SAVERESTOREDATA *pSaveData;
if (size <= 0)
size = 0x80000;
pSaveData = (SAVERESTOREDATA *)Mem_Calloc(sizeof(SAVERESTOREDATA) + (sizeof(ENTITYTABLE) * g_psv.num_edicts) + size, sizeof(char));
pSaveData->pTable = (ENTITYTABLE *)(pSaveData + 1);
pSaveData->tokenSize = 0;
pSaveData->tokenCount = 0xFFF;
pSaveData->pTokens = (char **)Mem_Calloc(0xFFF, sizeof(char *));
for (i = 0; i < g_psv.num_edicts; i++)
{
pEdict = &g_psv.edicts[i];
pSaveData->pTable[i].id = i;
pSaveData->pTable[i].pent = pEdict;
pSaveData->pTable[i].flags = 0;
pSaveData->pTable[i].location = 0;
pSaveData->pTable[i].size = 0;
pSaveData->pTable[i].classname = 0;
}
pSaveData->tableCount = g_psv.num_edicts;
pSaveData->connectionCount = 0;
pSaveData->size = 0;
pSaveData->bufferSize = size;
pSaveData->fUseLandmark = 0;
pSaveData->pBaseData = (char *)(pSaveData->pTable + g_psv.num_edicts);
pSaveData->pCurrentData = (char *)(pSaveData->pTable + g_psv.num_edicts);
gGlobalVariables.pSaveData = pSaveData;
pSaveData->time = gGlobalVariables.time;
pSaveData->vecLandmarkOffset[0] = vec3_origin[0];
pSaveData->vecLandmarkOffset[1] = vec3_origin[1];
pSaveData->vecLandmarkOffset[2] = vec3_origin[2];
return pSaveData;
}
/* <3e17e> ../engine/host_cmd.c:2029 */
void SaveExit(SAVERESTOREDATA *save)
{
if (save->pTokens)
{
Mem_Free(save->pTokens);
save->pTokens = NULL;
save->tokenCount = 0;
}
Mem_Free(save);
gGlobalVariables.pSaveData = NULL;
}
/* <3f65f> ../engine/host_cmd.c:2044 */
qboolean SaveGameSlot(const char *pSaveName, const char *pSaveComment)
{
char hlPath[256];
char name[256];
char *pTokenData;
int tag;
int i;
FILE *pFile;
SAVERESTOREDATA *pSaveData;
GAME_HEADER gameHeader;
FS_CreateDirHierarchy(Host_SaveGameDirectory(), "GAMECONFIG");
pSaveData = SaveGamestate();
if (!pSaveData)
return FALSE;
SaveExit(pSaveData);
pSaveData = SaveInit(0);
Q_snprintf(hlPath, sizeof(hlPath), "%s*.HL?", Host_SaveGameDirectory());
COM_FixSlashes(hlPath);
gameHeader.mapCount = DirectoryCount(hlPath);
Q_strncpy(gameHeader.mapName, g_psv.name, 31);
gameHeader.mapName[31] = 0;
Q_strncpy(gameHeader.comment, pSaveComment, 79);
gameHeader.comment[79] = 0;
gEntityInterface.pfnSaveWriteFields(pSaveData, "GameHeader", &gameHeader, gGameHeaderDescription, ARRAYSIZE(gGameHeaderDescription));
gEntityInterface.pfnSaveGlobalState(pSaveData);
pTokenData = NULL;
for (i = 0; i < pSaveData->tokenCount; i++)
{
if (pSaveData->pTokens[i])
{
pSaveData->size += Q_strlen(pSaveData->pTokens[i]) + 1;
if (pSaveData->size > pSaveData->bufferSize)
{
Con_Printf("Token Table Save/Restore overflow!");
pSaveData->size = pSaveData->bufferSize;
break;
}
pTokenData = pSaveData->pCurrentData;
do
{
*pTokenData++ = *pSaveData->pTokens[i]++;
}
while (*pSaveData->pTokens[i]);
pSaveData->pCurrentData = pTokenData;
}
else
{
if (pSaveData->size + 1 > pSaveData->bufferSize)
{
Con_Printf("Token Table Save/Restore overflow!");
pSaveData->size = pSaveData->bufferSize;
break;
}
pTokenData = pSaveData->pCurrentData;
*pTokenData = 0;
pSaveData->pCurrentData = pTokenData + 1;
}
}
pSaveData->tokenSize = (int)(pSaveData->pCurrentData - pTokenData);
if (pSaveData->size < pSaveData->bufferSize)
pSaveData->size -= pSaveData->tokenSize;
Q_snprintf(name, 252, "%s%s", Host_SaveGameDirectory(), pSaveName);
COM_DefaultExtension(name, ".sav");
COM_FixSlashes(name);
Con_DPrintf("Saving game to %s...\n", name);
if (Q_stricmp(pSaveName, "quick") || Q_stricmp(pSaveName, "autosave"))
Host_SaveAgeList(pSaveName, 1);
pFile = FS_OpenPathID(name, "wb", "GAMECONFIG");
tag = MAKEID('J','S','A','V');
FS_Write(&tag, sizeof(int), 1, pFile);
tag = SAVEGAME_VERSION;
FS_Write(&tag, sizeof(int), 1, pFile);
FS_Write(&pSaveData->size, sizeof(int), 1, pFile);
FS_Write(&pSaveData->tokenCount, sizeof(int), 1, pFile);
FS_Write(&pSaveData->tokenSize, sizeof(int), 1, pFile);
FS_Write(pSaveData->pCurrentData, pSaveData->tokenSize, 1, pFile);
FS_Write(pSaveData->pBaseData, pSaveData->size, 1, pFile);
DirectoryCopy(hlPath, pFile);
FS_Close(pFile);
SaveExit(pSaveData);
return TRUE;
}
/* <3dadd> ../engine/host_cmd.c:2150 */
void Host_Savegame_f(void)
{
char szComment[80];
char szTemp[80];
if (!Host_ValidSave())
return;
if (Cmd_Argc() != 2)
{
Con_DPrintf("save <savename> : save a game\n");
return;
}
if (Q_strstr(Cmd_Argv(1), ".."))
{
Con_DPrintf("Relative pathnames are not allowed.\n");
return;
}
g_pSaveGameCommentFunc(szTemp, 80);
Q_snprintf(szComment, sizeof(szComment) - 1,"%-64.64s %02d:%02d", szTemp, (int)(g_psv.time / 60.0), (int)fmod(g_psv.time, 60.0));
SaveGameSlot(Cmd_Argv(1), szComment);
CL_HudMessage("GAMESAVED");
}
/* <3d704> ../engine/host_cmd.c:2185 */
void Host_AutoSave_f(void)
{
char szComment[80];
char szTemp[80];
if (Host_ValidSave())
{
g_pSaveGameCommentFunc(szTemp, 80);
Q_snprintf(szComment, sizeof(szComment) - 1, "%-64.64s %02d:%02d", szTemp, (int)(g_psv.time / 60.0), (int)fmod(g_psv.time, 60.0));
szComment[sizeof(szComment) - 1] = 0;
SaveGameSlot("autosave", szComment);
}
}
/* <3f8d1> ../engine/host_cmd.c:2203 */
qboolean SaveGame(const char *pszSlot, const char *pszComment)
{
qboolean qret;
qboolean q;
q = scr_skipupdate;
scr_skipupdate = TRUE;
qret = SaveGameSlot(pszSlot, pszComment);
scr_skipupdate = q;
return qret;
}
/* <3d658> ../engine/host_cmd.c:2217 */
int SaveReadHeader(FileHandle_t pFile, GAME_HEADER *pHeader, int readGlobalState)
{
int i;
int tag;
int size;
int tokenCount;
int tokenSize;
char *pszTokenList;
SAVERESTOREDATA *pSaveData;
FS_Read(&tag, sizeof(int), 1, pFile);
if (tag != MAKEID('J','S','A','V'))
{
FS_Close(pFile);
return 0;
}
FS_Read(&tag, sizeof(int), 1, pFile);
if (tag != SAVEGAME_VERSION)
{
FS_Close(pFile);
return 0;
}
FS_Read(&size, sizeof(int), 1, pFile);
FS_Read(&tokenCount, sizeof(int), 1, pFile);
FS_Read(&tokenSize, sizeof(int), 1, pFile);
pSaveData = (SAVERESTOREDATA *)Mem_Calloc(sizeof(SAVERESTOREDATA) + tokenSize + size, sizeof(char));
pSaveData->tableCount = 0;
pSaveData->pTable = NULL;
pSaveData->connectionCount = 0;
pszTokenList = (char *)(pSaveData + 1);
if (tokenSize > 0)
{
pSaveData->tokenCount = tokenCount;
pSaveData->tokenSize = tokenSize;
FS_Read(pszTokenList, tokenSize, 1, pFile);
if (!pSaveData->pTokens)
pSaveData->pTokens = (char **)Mem_Calloc(tokenCount, sizeof(char *));
for (i = 0; i < tokenCount; i++)
{
if (*pszTokenList)
pSaveData->pTokens[i] = pszTokenList;
else
pSaveData->pTokens[i] = NULL;
while (*pszTokenList++);
}
}
pSaveData->size = 0;
pSaveData->bufferSize = size;
pSaveData->fUseLandmark = 0;
pSaveData->time = 0.0f;
pSaveData->pCurrentData = pszTokenList;
pSaveData->pBaseData = pszTokenList;
FS_Read(pSaveData->pBaseData, size, 1, pFile);
gEntityInterface.pfnSaveReadFields(pSaveData, "GameHeader", pHeader, gGameHeaderDescription, ARRAYSIZE(gGameHeaderDescription));
if (readGlobalState)
gEntityInterface.pfnRestoreGlobalState(pSaveData);
SaveExit(pSaveData);
return 1;
}
/* <3ea80> ../engine/host_cmd.c:2289 */
void SaveReadComment(FileHandle_t f, char *name)
{
GAME_HEADER gameHeader;
if (SaveReadHeader(f, &gameHeader, 0))
Q_strcpy(name, gameHeader.comment);
}
/* <3d97a> ../engine/host_cmd.c:2302 */
void Host_Loadgame_f(void)
{
if (cmd_source != src_command)
return;
if (Cmd_Argc() != 2)
{
Con_Printf("load <savename> : load a game\n");
return;
}
if (!Host_Load(Cmd_Argv(1)))
Con_Printf("Error loading saved game\n");
}
/* <3fe89> ../engine/host_cmd.c:2323 */
int LoadGame(const char *pName)
{
int iRet;
qboolean q;
q = scr_skipupdate;
scr_skipupdate = TRUE;
iRet = Host_Load(pName);
scr_skipupdate = q;
return iRet;
}
/* <3fccf> ../engine/host_cmd.c:2334 */
int Host_Load(const char *pName)
{
FILE *pFile;
GAME_HEADER gameHeader;
char name[256];
int nSlot;
if (!pName || !pName[0])
return 0;
if (Q_strstr(pName, ".."))
{
Con_Printf("Relative pathnames are not allowed.\n");
return 0;
}
if (*pName == '_' && COM_TokenWaiting((char *)&pName[1]))
{
nSlot = Q_atoi(pName);
if (nSlot < 1 || nSlot > 12)
return 0;
Q_snprintf(name, 252, "%sHalf-Life-%i", Host_SaveGameDirectory(), nSlot);
}
else
Q_snprintf(name, 252, "%s%s", Host_SaveGameDirectory(), pName);
name[251] = 0;
if (!g_psvs.dll_initialized)
Host_InitializeGameDLL();
COM_DefaultExtension(name, ".sav");
COM_FixSlashes(name);
name[255] = 0;
Con_Printf("Loading game from %s...\n", name);
pFile = FS_OpenPathID(name, "rb", "GAMECONFIG");
if (!pFile)
return 0;
Host_ClearGameState();
if (!SaveReadHeader(pFile, &gameHeader, 1))
{
giStateInfo = 1;
Cbuf_AddText("\ndisconnect\n");
return 0;
}
g_pcls.demonum = -1;
SV_InactivateClients();
SCR_BeginLoadingPlaque(FALSE);
DirectoryExtract(pFile, gameHeader.mapCount);
FS_Close(pFile);
Cvar_SetValue("deathmatch", 0.0);
Cvar_SetValue("coop", 0.0);
if (!Q_stricmp(com_gamedir,"valve")
|| !Q_stricmp(com_gamedir,"bshift")
|| !Q_stricmp(com_gamedir,"gearbox"))
{
g_psvs.maxclients = 1;
Cvar_SetValue("maxplayers", 1.0);
}
Q_snprintf(name, sizeof(name), "map %s\n", gameHeader.mapName);
CL_Disconnect();
Host_Map(FALSE, name, gameHeader.mapName, TRUE);
return 1;
}
/* <3ed7d> ../engine/host_cmd.c:2439 */
SAVERESTOREDATA *SaveGamestate(void)
{
char name[256];
char *pTableData;
char *pTokenData;
FILE *pFile;
int i;
int dataSize;
int tableSize;
edict_t *pent;
SAVE_HEADER header;
SAVERESTOREDATA *pSaveData;
SAVELIGHTSTYLE light;
if (!gEntityInterface.pfnParmsChangeLevel)
return NULL;
#ifdef REHLDS_FIXES
Q_memset(&header, 0, sizeof(SAVE_HEADER));
#endif // REHLDS_FIXES
FS_CreateDirHierarchy(Host_SaveGameDirectory(), "GAMECONFIG");
pSaveData = SaveInit(0);
Q_snprintf(name, sizeof(name), "%s%s.HL1", Host_SaveGameDirectory(), g_psv.name);
COM_FixSlashes(name);
gEntityInterface.pfnParmsChangeLevel();
header.version = build_number();
header.skillLevel = (int)skill.value;
header.entityCount = pSaveData->tableCount;
header.time = g_psv.time;
header.connectionCount = pSaveData->connectionCount;
Q_strncpy(header.skyName, sv_skyname.string, sizeof(header.skyName) - 1);
header.skyName[sizeof(header.skyName) - 1] = 0;
pSaveData->time = 0.0f;
header.skyColor_r = (int)sv_skycolor_r.value;
header.skyColor_g = (int)sv_skycolor_g.value;
header.skyColor_b = (int)sv_skycolor_b.value;
header.skyVec_x = sv_skyvec_x.value;
header.skyVec_y = sv_skyvec_y.value;
header.skyVec_z = sv_skyvec_z.value;
Q_strncpy(header.mapName, g_psv.name, sizeof(header.mapName) - 1);
header.mapName[sizeof(header.mapName) - 1] = 0;
for (i = 0; i < MAX_LIGHTSTYLES; i++)
{
if (g_psv.lightstyles[i])
header.lightStyleCount++;
}
gEntityInterface.pfnSaveWriteFields(pSaveData, "Save Header", &header, gSaveHeaderDescription, ARRAYSIZE(gSaveHeaderDescription));
pSaveData->time = header.time;
for (i = 0; i < pSaveData->connectionCount; i++)
gEntityInterface.pfnSaveWriteFields(pSaveData, "ADJACENCY", &pSaveData->levelList[i], gAdjacencyDescription, ARRAYSIZE(gAdjacencyDescription));
for (i = 0; i < MAX_LIGHTSTYLES; i++)
{
if (g_psv.lightstyles[i])
{
light.index = i;
Q_strncpy(light.style, g_psv.lightstyles[i], 63);
light.style[63] = 0;
gEntityInterface.pfnSaveWriteFields(pSaveData, "LIGHTSTYLE", &light, gLightstyleDescription, ARRAYSIZE(gLightstyleDescription));
}
}
dataSize = pSaveData->size;
pTableData = pSaveData->pCurrentData;
tableSize = 0;
for (i = 0; i < g_psv.num_edicts; i++)
{
pent = &g_psv.edicts[i];
pSaveData->currentIndex = i;
pSaveData->pTable[i].location = pSaveData->size;
if (!pent->free)
{
gEntityInterface.pfnSave(pent, pSaveData);
if (SV_IsPlayerIndex(i))
pSaveData->pTable[i].flags |= FENTTABLE_PLAYER;
}
}
for (i = 0; i < g_psv.num_edicts; i++)
gEntityInterface.pfnSaveWriteFields(pSaveData, "ETABLE", &pSaveData->pTable[i], gEntityTableDescription, ARRAYSIZE(gEntityTableDescription));
pTokenData = NULL;
for (i = 0; i < pSaveData->tokenCount; i++)
{
if (pSaveData->pTokens[i])
{
pTokenData = pSaveData->pCurrentData;
do
{
*pTokenData++ = *pSaveData->pTokens[i]++;
}
while (*pSaveData->pTokens[i]);
pSaveData->pCurrentData = pTokenData;
}
else
{
pTokenData = pSaveData->pCurrentData;
*pTokenData = 0;
pSaveData->pCurrentData = pTokenData + 1;
}
}
pSaveData->tokenSize = (int)(pSaveData->pCurrentData - pTokenData);
COM_CreatePath(name);
pFile = FS_OpenPathID(name, "wb", "GAMECONFIG");
if (!pFile)
{
Con_Printf("Unable to open save game file %s.", name);
return NULL;
}
i = SAVEFILE_HEADER;
FS_Write(&i, sizeof(int), 1, pFile);
i = SAVEGAME_VERSION;
FS_Write(&i, sizeof(int), 1, pFile);
FS_Write(&pSaveData->size, sizeof(int), 1, pFile);
FS_Write(&pSaveData->tableCount, sizeof(int), 1, pFile);
FS_Write(&pSaveData->tokenCount, sizeof(int), 1, pFile);
FS_Write(&pSaveData->tokenSize, sizeof(int), 1, pFile);
FS_Write(pSaveData->pCurrentData, pSaveData->tokenSize, 1, pFile);
FS_Write(pTableData, tableSize, 1, pFile);
FS_Write(pSaveData->pBaseData, dataSize, 1, pFile);
FS_Close(pFile);
EntityPatchWrite(pSaveData, g_psv.name);
Q_snprintf(name, sizeof(name), "%s%s.HL2", Host_SaveGameDirectory(), g_psv.name);
COM_FixSlashes(name);
CL_Save(name);
return pSaveData;
}
/* <3d6e8> ../engine/host_cmd.c:2592 */
void CL_Save(const char *name)
{
}
/* <3eb39> ../engine/host_cmd.c:2623 */
void EntityInit(edict_t *pEdict, int className)
{
ENTITYINIT pEntityInit;
if (!className)
Sys_Error("Bad class!!\n");
ReleaseEntityDLLFields(pEdict);
InitEntityDLLFields(pEdict);
pEdict->v.classname = className;
pEntityInit = GetEntityInit(&pr_strings[className]);
if (pEntityInit)
pEntityInit(&pEdict->v);
}
/* <3eb9c> ../engine/host_cmd.c:2640 */
SAVERESTOREDATA *LoadSaveData(const char *level)
{
char name[MAX_PATH];
char *pszTokenList;
FILE *pFile;
int i;
int size;
int tokenCount;
int tokenSize;
int tableCount;
SAVERESTOREDATA *pSaveData;
Q_snprintf(name, sizeof(name), "%s%s.HL1", Host_SaveGameDirectory(), level);
COM_FixSlashes(name);
Con_Printf("Loading game from %s...\n", name);
pFile = FS_OpenPathID(name, "rb", "GAMECONFIG");
if (!pFile)
{
Con_Printf("ERROR: couldn't open.\n");
return NULL;
}
FS_Read(&i, sizeof(int), 1, pFile);
if (i != SAVEFILE_HEADER)
{
FS_Close(pFile);
return NULL;
}
FS_Read(&i, sizeof(int), 1, pFile);
if (i != SAVEGAME_VERSION)
{
FS_Close(pFile);
return NULL;
}
FS_Read(&size, sizeof(int), 1, pFile);
FS_Read(&tableCount, sizeof(int), 1, pFile);
FS_Read(&tokenCount, sizeof(int), 1, pFile);
FS_Read(&tokenSize, sizeof(int), 1, pFile);
pSaveData = (SAVERESTOREDATA *)Mem_Calloc(size + tokenSize + sizeof(ENTITYTABLE) * tableCount + sizeof(SAVERESTOREDATA), 1u);
pSaveData->tableCount = tableCount;
pSaveData->tokenCount = tokenCount;
pSaveData->tokenSize = tokenSize;
Q_strncpy(pSaveData->szCurrentMapName, level, sizeof(pSaveData->szCurrentMapName) - 1);
pSaveData->szCurrentMapName[sizeof(pSaveData->szCurrentMapName) - 1] = 0;
pszTokenList = (char *)(pSaveData + 1);
if (tokenSize > 0)
{
FS_Read(pszTokenList, tokenSize, 1, pFile);
if (!pSaveData->pTokens)
{
pSaveData->pTokens = (char **)Mem_Calloc(tokenCount, sizeof(char *));
}
for (i = 0; i < tokenCount; i++)
{
if (*pszTokenList)
pSaveData->pTokens[i] = pszTokenList;
else
pSaveData->pTokens[i] = NULL;
while (*pszTokenList++);
}
}
pSaveData->pTable = (ENTITYTABLE *)pszTokenList;
pSaveData->connectionCount = 0;
pSaveData->size = 0;
pSaveData->pBaseData = pszTokenList;
pSaveData->pCurrentData = pszTokenList;
pSaveData->fUseLandmark = 1;
pSaveData->bufferSize = size;
pSaveData->time = 0.0f;
pSaveData->vecLandmarkOffset[0] = 0.0f;
pSaveData->vecLandmarkOffset[1] = 0.0f;
pSaveData->vecLandmarkOffset[2] = 0.0f;
gGlobalVariables.pSaveData = pSaveData;
FS_Read(pSaveData->pBaseData, size, 1, pFile);
FS_Close(pFile);
return pSaveData;
}
/* <3ec7a> ../engine/host_cmd.c:2724 */
void ParseSaveTables(SAVERESTOREDATA *pSaveData, SAVE_HEADER *pHeader, int updateGlobals)
{
int i;
SAVELIGHTSTYLE light;
for (i = 0; i < pSaveData->tableCount; i++)
{
gEntityInterface.pfnSaveReadFields(pSaveData, "ETABLE", &(pSaveData->pTable[i]), gEntityTableDescription, ARRAYSIZE(gEntityTableDescription));
pSaveData->pTable[i].pent = NULL;
}
pSaveData->size = 0;
pSaveData->pBaseData = pSaveData->pCurrentData;
gEntityInterface.pfnSaveReadFields(pSaveData, "Save Header", pHeader, gSaveHeaderDescription, ARRAYSIZE(gSaveHeaderDescription));
pSaveData->connectionCount = pHeader->connectionCount;
pSaveData->fUseLandmark = 1;
pSaveData->time = pHeader->time;
pSaveData->vecLandmarkOffset[0] = 0;
pSaveData->vecLandmarkOffset[1] = 0;
pSaveData->vecLandmarkOffset[2] = 0;
for (i = 0; i < pSaveData->connectionCount; i++)
{
gEntityInterface.pfnSaveReadFields(pSaveData, "ADJACENCY", &(pSaveData->levelList[i]), gAdjacencyDescription, ARRAYSIZE(gAdjacencyDescription));
}
for (i = 0; i < pHeader->lightStyleCount; i++)
{
gEntityInterface.pfnSaveReadFields(pSaveData, "LIGHTSTYLE", &light, gLightstyleDescription, ARRAYSIZE(gLightstyleDescription));
if (updateGlobals)
{
g_psv.lightstyles[light.index] = (char *)Hunk_Alloc(Q_strlen(light.style) + 1);
Q_strncpy(g_psv.lightstyles[light.index], light.style, 3);
g_psv.lightstyles[light.index][3] = 0;
}
}
}
/* <3ece6> ../engine/host_cmd.c:2770 */
void EntityPatchWrite(SAVERESTOREDATA *pSaveData, const char *level)
{
char name[MAX_PATH];
FILE *pFile;
int i;
int size = 0;
Q_snprintf(name, sizeof(name), "%s%s.HL3", Host_SaveGameDirectory(), level);
COM_FixSlashes(name);
pFile = FS_OpenPathID(name, "wb", "GAMECONFIG");
if (!pFile)
return;
for (i = 0; i < pSaveData->tableCount; i++)
{
if (pSaveData->pTable[i].flags & FENTTABLE_REMOVED)
size++;
}
FS_Write(&size, sizeof(int), 1, pFile);
for (i = 0; i < pSaveData->tableCount; i++)
{
if (pSaveData->pTable[i].flags & FENTTABLE_REMOVED)
FS_Write(&i, sizeof(int), 1, pFile);
}
FS_Close(pFile);
}
/* <3eed5> ../engine/host_cmd.c:2802 */
void EntityPatchRead(SAVERESTOREDATA *pSaveData, const char *level)
{
char name[MAX_PATH];
FILE *pFile;
int i;
int size;
int entityId;
Q_snprintf(name, sizeof(name), "%s%s.HL3", Host_SaveGameDirectory(), level);
COM_FixSlashes(name);
pFile = FS_OpenPathID(name, "rb", "GAMECONFIG");
if (!pFile)
return;
FS_Read(&size, 4, 1, pFile);
for (i = 0; i < size; i++)
{
FS_Read(&entityId, 4, 1, pFile);
pSaveData->pTable[entityId].flags = FENTTABLE_REMOVED;
}
}
/* <3ef7c> ../engine/host_cmd.c:2826 */
int LoadGamestate(char *level, int createPlayers)
{
int i;
edict_t *pent;
SAVE_HEADER header;
SAVERESTOREDATA *pSaveData;
ENTITYTABLE *pEntInfo;
pSaveData = LoadSaveData(level);
if (!pSaveData)
return 0;
ParseSaveTables(pSaveData, &header, 1);
EntityPatchRead(pSaveData, level);
Q_strncpy(g_psv.name, header.mapName, sizeof(g_psv.name) - 1);
g_psv.name[sizeof(g_psv.name) - 1] = 0;
Cvar_Set("sv_skyname", header.skyName);
Cvar_SetValue("skill", header.skillLevel);
Cvar_SetValue("sv_skycolor_r", header.skyColor_r);
Cvar_SetValue("sv_skycolor_g", header.skyColor_g);
Cvar_SetValue("sv_skycolor_b", header.skyColor_b);
Cvar_SetValue("sv_skyvec_x", header.skyVec_x);
Cvar_SetValue("sv_skyvec_y", header.skyVec_y);
Cvar_SetValue("sv_skyvec_z", header.skyVec_z);
for (i = 0; i < pSaveData->tableCount; i++)
{
pent = NULL;
pEntInfo = &pSaveData->pTable[i];
if (pEntInfo->classname && pEntInfo->size && !(pEntInfo->flags & FENTTABLE_REMOVED))
{
if (pEntInfo->id)
{
if (pEntInfo->id > g_psvs.maxclients)
pEntInfo->pent = CreateNamedEntity(pEntInfo->classname);
else
{
if (!(pEntInfo->flags & FENTTABLE_PLAYER))
Sys_Error("ENTITY IS NOT A PLAYER: %d\n", i);
pent = g_psvs.clients[pEntInfo->id - 1].edict;
if (createPlayers && pent)
EntityInit(pent, pEntInfo->classname);
else
pent = NULL;
}
}
else
{
pent = g_psv.edicts;
EntityInit(pent, pEntInfo->classname);
}
}
pEntInfo->pent = pent;
}
for (i = 0; i < pSaveData->tableCount; i++)
{
pEntInfo = &pSaveData->pTable[i];
pent = pEntInfo->pent;
pSaveData->size = pEntInfo->location;
pSaveData->pCurrentData = &pSaveData->pBaseData[pEntInfo->location];
if (pent)
{
if (gEntityInterface.pfnRestore(pent, pSaveData, 0) < 0)
{
ED_Free(pent);
pEntInfo->pent = NULL;
}
else
SV_LinkEdict(pent, FALSE);
}
}
SaveExit(pSaveData);
g_psv.time = header.time;
return 1;
}
/* <3da9b> ../engine/host_cmd.c:2911 */
int EntryInTable(SAVERESTOREDATA *pSaveData, const char *pMapName, int index)
{
int i;
for (i = index + 1; i < pSaveData->connectionCount; i++)
{
if ( !Q_strcmp(pSaveData->levelList[i].mapName, pMapName))
return i;
}
return -1;
}
/* <3f117> ../engine/host_cmd.c:2926 */
void LandmarkOrigin(SAVERESTOREDATA *pSaveData, vec_t *output, const char *pLandmarkName)
{
int i;
for (i = 0; i < pSaveData->connectionCount; i++)
{
if (!Q_strcmp(pSaveData->levelList[i].landmarkName, pLandmarkName))
{
output[0] = pSaveData->levelList[i].vecLandmarkOrigin[0];
output[1] = pSaveData->levelList[i].vecLandmarkOrigin[1];
output[2] = pSaveData->levelList[i].vecLandmarkOrigin[2];
return;
}
}
output[0] = 0.0f;
output[1] = 0.0f;
output[2] = 0.0f;
}
/* <3f18c> ../engine/host_cmd.c:2945 */
int EntityInSolid(edict_t *pent)
{
vec3_t point;
if (pent->v.movetype == MOVETYPE_FOLLOW)
{
edict_t *pAimEnt = pent->v.aiment;
if (pAimEnt && pAimEnt->v.flags & FL_CLIENT)
return 0;
}
g_groupmask = pent->v.groupinfo;
point[0] = (pent->v.absmin[0] + pent->v.absmax[0]) * 0.5f;
point[1] = (pent->v.absmin[1] + pent->v.absmax[1]) * 0.5f;
point[2] = (pent->v.absmin[2] + pent->v.absmax[2]) * 0.5f;
return (SV_PointContents(point) == CONTENTS_SOLID);
}
/* <3f1de> ../engine/host_cmd.c:2965 */
int CreateEntityList(SAVERESTOREDATA *pSaveData, int levelMask)
{
int i;
int movedCount = 0;
int active;
edict_t *pent;
ENTITYTABLE *pEntInfo;
if (pSaveData->tableCount < 1)
return 0;
for (i = 0; i < pSaveData->tableCount; i++)
{
pent = NULL;
pEntInfo = &pSaveData->pTable[i];
if (pEntInfo->classname && pEntInfo->size && pEntInfo->id)
{
active = !!(pEntInfo->flags & levelMask);
if (SV_IsPlayerIndex(pEntInfo->id))
{
client_t *cl = &g_psvs.clients[pEntInfo->id - 1];
if (active && cl)
{
pent = cl->edict;
if (pent && !pent->free)
{
if (!(pEntInfo->flags & FENTTABLE_PLAYER))
Sys_Error("ENTITY IS NOT A PLAYER: %d\n", i);
if (cl->active)
EntityInit(pent, pEntInfo->classname);
}
}
}
else if (active)
pent = CreateNamedEntity(pEntInfo->classname);
}
pEntInfo->pent = pent;
}
for (i = 0; i < pSaveData->tableCount; i++)
{
pEntInfo = &pSaveData->pTable[i];
pent = pEntInfo->pent;
pSaveData->currentIndex = i;
pSaveData->size = pEntInfo->location;
pSaveData->pCurrentData = &pSaveData->pBaseData[pEntInfo->location];
if (pent && (pEntInfo->flags & levelMask))
{
if (pEntInfo->flags & FENTTABLE_GLOBAL)
{
Con_DPrintf("Merging changes for global: %s\n", &pr_strings[pEntInfo->classname]);
gEntityInterface.pfnRestore(pent, pSaveData, 1);
ED_Free(pent);
}
else
{
Con_DPrintf("Transferring %s (%d)\n", &pr_strings[pEntInfo->classname], NUM_FOR_EDICT(pent));
if (gEntityInterface.pfnRestore(pent, pSaveData, 0) < 0)
ED_Free(pent);
else
{
SV_LinkEdict(pent, FALSE);
if (!(pEntInfo->flags & FENTTABLE_PLAYER) && EntityInSolid(pent))
{
Con_DPrintf("Suppressing %s\n", &pr_strings[pEntInfo->classname]);
ED_Free(pent);
}
else
{
movedCount++;
pEntInfo->flags = FENTTABLE_REMOVED;
}
}
}
}
}
return movedCount;
}
/* <3f2b7> ../engine/host_cmd.c:3047 */
void LoadAdjacentEntities(const char *pOldLevel, const char *pLandmarkName)
{
int i;
int test;
int flags;
int index;
int movedCount = 0;
SAVE_HEADER header;
vec3_t landmarkOrigin;
SAVERESTOREDATA *pSaveData;
SAVERESTOREDATA currentLevelData;
Q_memset(&currentLevelData, 0, sizeof(SAVERESTOREDATA));
gGlobalVariables.pSaveData = &currentLevelData;
gEntityInterface.pfnParmsChangeLevel();
for (i = 0; i < currentLevelData.connectionCount; i++)
{
for (test = 0; test < i; test++)
{
// Only do maps once
if ( !Q_strcmp(currentLevelData.levelList[i].mapName, currentLevelData.levelList[test].mapName))
break;
}
// Map was already in the list
if (test < i)
continue;
pSaveData = LoadSaveData(currentLevelData.levelList[i].mapName);
if (pSaveData)
{
ParseSaveTables(pSaveData, &header, 0);
EntityPatchRead(pSaveData, currentLevelData.levelList[i].mapName);
pSaveData->time = g_psv.time;
pSaveData->fUseLandmark = 1;
flags = 0;
LandmarkOrigin(&currentLevelData, landmarkOrigin, pLandmarkName);
LandmarkOrigin(pSaveData, pSaveData->vecLandmarkOffset, pLandmarkName);
pSaveData->vecLandmarkOffset[0] -= landmarkOrigin[0];
pSaveData->vecLandmarkOffset[1] -= landmarkOrigin[1];
pSaveData->vecLandmarkOffset[2] -= landmarkOrigin[2];
if (!Q_strcmp(currentLevelData.levelList[i].mapName, pOldLevel))
flags |= FENTTABLE_PLAYER;
index = -1;
while (1)
{
index = EntryInTable(pSaveData, g_psv.name, index);
if (index < 0)
break;
flags |= (1<<index);
}
if (flags)
movedCount = CreateEntityList(pSaveData, flags);
// If ents were moved, rewrite entity table to save file
if (movedCount)
EntityPatchWrite(pSaveData, currentLevelData.levelList[i].mapName);
SaveExit(pSaveData);
}
}
gGlobalVariables.pSaveData = NULL;
}
/* <3f445> ../engine/host_cmd.c:3111 */
int FileSize(FileHandle_t pFile)
{
if (!pFile)
return 0;
return FS_Size(pFile);
}
/* <3f482> ../engine/host_cmd.c:3121 */
void FileCopy(FileHandle_t pOutput, FileHandle_t pInput, int fileSize)
{
char buf[1024];
int size;
while (fileSize > 0)
{
if (fileSize > sizeof(buf))
size = sizeof(buf);
else
size = fileSize;
FS_Read(buf, size, 1, pInput);
FS_Write(buf, size, 1, pOutput);
fileSize -= size;
}
}
/* <3f50f> ../engine/host_cmd.c:3140 */
void DirectoryCopy(const char *pPath, FileHandle_t pFile)
{
const char *findfn;
char basefindfn[MAX_PATH];
int fileSize;
FILE *pCopy;
char szName[MAX_PATH];
findfn = Sys_FindFirst(pPath, basefindfn);
while (findfn != NULL)
{
Q_snprintf(szName, sizeof(szName), "%s%s", Host_SaveGameDirectory(), findfn);
COM_FixSlashes(szName);
pCopy = FS_OpenPathID(szName, "rb", "GAMECONFIG");
fileSize = FS_Size(pCopy);
FS_Write(findfn, MAX_PATH, 1, pFile);
FS_Write(&fileSize, sizeof(int), 1, pFile);
FileCopy(pFile, pCopy, fileSize);
FS_Close(pCopy);
findfn = Sys_FindNext(basefindfn);
}
Sys_FindClose();
}
/* <3f973> ../engine/host_cmd.c:3167 */
void DirectoryExtract(FileHandle_t pFile, int fileCount)
{
int i;
int fileSize;
FILE *pCopy;
char szName[MAX_PATH];
char fileName[MAX_PATH];
for (i = 0; i < fileCount; i++)
{
FS_Read(fileName, sizeof(fileName), 1, pFile);
FS_Read(&fileSize, sizeof(int), 1, pFile);
Q_snprintf(szName, sizeof(szName), "%s%s", Host_SaveGameDirectory(), fileName);
COM_FixSlashes(szName);
pCopy = FS_OpenPathID(szName, "wb", "GAMECONFIG");
FileCopy(pCopy, pFile, fileCount);
FS_Close(pCopy);
}
}
/* <3f627> ../engine/host_cmd.c:3187 */
int DirectoryCount(const char *pPath)
{
int count;
const char *findfn;
count = 0;
findfn = Sys_FindFirstPathID(pPath, "GAMECONFIG");
while (findfn != NULL)
{
findfn = Sys_FindNext(NULL);
count++;
}
Sys_FindClose();
return count;
}
/* <3fa97> ../engine/host_cmd.c:3209 */
void Host_ClearSaveDirectory(void)
{
char szName[MAX_PATH];
const char *pfn;
Q_snprintf(szName, sizeof(szName), "%s", Host_SaveGameDirectory());
Q_strncat(szName, "*.HL?", sizeof(szName) - Q_strlen(szName) - 1);
COM_FixSlashes(szName);
if (Sys_FindFirstPathID(szName, "GAMECONFIG") != NULL)
{
Sys_FindClose();
Q_snprintf(szName, sizeof(szName), "%s", Host_SaveGameDirectory());
COM_FixSlashes(szName);
FS_CreateDirHierarchy(szName, "GAMECONFIG");
Q_strncat(szName, "*.HL?", sizeof(szName) - Q_strlen(szName) - 1);
for (pfn = Sys_FindFirstPathID(szName, "GAMECONFIG"); pfn; pfn = Sys_FindNext(NULL))
{
Q_snprintf(szName, sizeof(szName), "%s%s", Host_SaveGameDirectory(), pfn);
FS_RemoveFile(szName, "GAMECONFIG");
}
}
Sys_FindClose();
}
/* <3fbe0> ../engine/host_cmd.c:3250 */
void Host_ClearGameState(void)
{
S_StopAllSounds(TRUE);
Host_ClearSaveDirectory();
if (gEntityInterface.pfnResetGlobalState)
gEntityInterface.pfnResetGlobalState();
}
/* <3d72c> ../engine/host_cmd.c:3262 */
void Host_Changelevel2_f(void)
{
char level[64];
char oldlevel[64];
char _startspot[64];
char *startspot;
SAVERESTOREDATA *pSaveData;
qboolean newUnit;
giActive = DLL_TRANS;
if (Cmd_Argc() < 2)
{
Con_Printf("changelevel2 <levelname> : continue game on a new level in the unit\n");
return;
}
if (!g_psv.active || g_pcls.demoplayback || g_psv.paused)
{
Con_Printf("Only the server may changelevel\n");
return;
}
if (g_psvs.maxclients > 1)
{
Con_Printf("changelevel2 <levelname> : not for use with multiplayer games\n");
return;
}
SCR_BeginLoadingPlaque(FALSE);
S_StopAllSounds(TRUE);
Q_strncpy(level, Cmd_Argv(1), sizeof(level) - 1);
level[sizeof(level) - 1] = 0;
if (Cmd_Argc() != 2)
{
startspot = &_startspot[0];
Q_strncpy(_startspot, Cmd_Argv(2), sizeof(_startspot) - 1);
_startspot[sizeof(_startspot) - 1] = 0;
}
else
startspot = NULL;
Q_strncpy(oldlevel, g_psv.name, sizeof(oldlevel) - 1);
oldlevel[sizeof(oldlevel) - 1] = 0;
pSaveData = SaveGamestate();
SV_ServerShutdown();
FS_LogLevelLoadStarted(level);
if (!SV_SpawnServer(FALSE, level, startspot))
Sys_Error("Host_Changelevel2: Couldn't load map %s\n", level);
if (pSaveData)
SaveExit(pSaveData);
newUnit = FALSE;
if (!LoadGamestate(level, 0))
{
newUnit = TRUE;
SV_LoadEntities();
}
LoadAdjacentEntities(oldlevel, startspot);
gGlobalVariables.time = g_psv.time;
g_psv.paused = TRUE;
g_psv.loadgame = TRUE;
if (newUnit && sv_newunit.value != 0.0f)
Host_ClearSaveDirectory();
SV_ActivateServer(0);
}
/* <3db8f> ../engine/host_cmd.c:3369 */
void Host_Version_f(void)
{
Con_Printf("Protocol version %i\nExe version %s (%s)\n", PROTOCOL_VERSION, gpszVersionString, gpszProductString);
#ifdef REHLDS_FIXES
Con_Printf("Exe build: " __TIME__ " " __DATE__ " (%i)\n", build_number());
#else // REHLDS_FIXES
#ifdef _WIN32
Con_Printf("Exe build: 11:17:24 Aug 8 2013 (%i)\n", build_number());
#else // _WIN32
Con_Printf("Exe build: 10:03:21 Aug 8 2013 (%i)\n", build_number());
#endif // _WIN32
#endif // REHLDS_FIXES
Con_Printf("ReHLDS API version %i.%i\n", REHLDS_API_VERSION_MAJOR, REHLDS_API_VERSION_MINOR);
}
/* <3d516> ../engine/host_cmd.c:3382 */
void Host_FullInfo_f(void)
{
char key[512];
char value[512];
char *o;
char *s;
if (Cmd_Argc() != 2)
{
Con_Printf("fullinfo <complete info string>\n");
return;
}
s = (char *)Cmd_Argv(1);
if (*s == '\\')
s++;
while (*s)
{
o = key;
while (*s && *s != '\\')
*o++ = *s++;
*o = 0;
if (!*s)
{
Con_Printf("MISSING VALUE\n");
return;
}
o = value;
s++;
while (*s && *s != '\\')
*o++ = *s++;
*o = 0;
if (*s)
s++;
if (cmd_source == src_command)
{
Info_SetValueForKey(g_pcls.userinfo, key, value, MAX_INFO_STRING);
Cmd_ForwardToServer();
return;
}
Info_SetValueForKey(host_client->userinfo, key, value, MAX_INFO_STRING);
host_client->sendinfo = TRUE;
}
}
/* <400a6> ../engine/host_cmd.c:3433 */
NOXREF void Host_KillVoice_f(void)
{
Voice_Deinit();
}
/* <3d50b> ../engine/host_cmd.c:3447 */
void Host_SetInfo_f(void)
{
if (Cmd_Argc() == 1)
{
Info_Print(g_pcls.userinfo);
return;
}
if (Cmd_Argc() != 3)
{
Con_Printf("usage: setinfo [ <key> <value> ]\n");
return;
}
if (cmd_source == src_command)
{
Info_SetValueForKey(g_pcls.userinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_INFO_STRING);
Cmd_ForwardToServer();
return;
}
Info_SetValueForKey(host_client->userinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_INFO_STRING);
host_client->sendinfo = TRUE;
}
/* <3d82c> ../engine/host_cmd.c:3471 */
void Host_Say(qboolean teamonly)
{
client_t *client;
client_t *save;
int j;
char *p;
char text[128];
//qboolean fromServer;//unsued?
if (g_pcls.state != ca_dedicated)
{
if (cmd_source != src_command)
return;
Cmd_ForwardToServer();
return;
}
if (Cmd_Argc () < 2)
return;
p = (char *)Cmd_Args();
if (!p)
return;
save = host_client;
if (*p == '"')
{
p++;
p[Q_strlen(p) - 1] = 0;
}
#ifdef REHLDS_FIXES
// I think '\x01' don't need in TextMsg
Q_snprintf(text, sizeof(text), "<%s> ", Cvar_VariableString("hostname"));
#else // REHLDS_FIXES
Q_snprintf(text, sizeof(text), "%c<%s> ", 1, Cvar_VariableString("hostname"));
#endif // REHLDS_FIXES
if (Q_strlen(p) > 63)
p[63] = 0;
j = sizeof(text) - 2 - Q_strlen(text);
if (Q_strlen(p) > (unsigned int)j)
p[j] = 0;
Q_strcat(text, p);
Q_strcat(text, "\n");
for (j = 0, client = g_psvs.clients; j < g_psvs.maxclients; j++, client++)
{
if (!client->active || !client->spawned || client->fakeclient)
continue;
host_client = client;
#ifdef REHLDS_FIXES
// Text can be unsafe (format %, localize #) therefore need to send text as argument. TextMsg is used here instead of SayText, because SayText in Half-Life doesn't support arguments.
PF_MessageBegin_I(MSG_ONE, RegUserMsg("TextMsg", -1), NULL, &g_psv.edicts[j + 1]);
PF_WriteByte_I(HUD_PRINTTALK);
PF_WriteString_I("%s");
PF_WriteString_I(text);
PF_MessageEnd_I();
#else // REHLDS_FIXES
PF_MessageBegin_I(MSG_ONE, RegUserMsg("SayText", -1), NULL, &g_psv.edicts[j + 1]);
PF_WriteByte_I(0);
PF_WriteString_I(text);
PF_MessageEnd_I();
#endif // REHLDS_FIXES
}
host_client = save;
Sys_Printf("%s", &text[1]);
Log_Printf("Server say \"%s\"\n", p);
}
/* <3e127> ../engine/host_cmd.c:3541 */
void Host_Say_f(void)
{
Host_Say(FALSE);
}
/* <3e0d0> ../engine/host_cmd.c:3547 */
void Host_Say_Team_f(void)
{
Host_Say(TRUE);
}
/* <3d4b1> ../engine/host_cmd.c:3553 */
void Host_Tell_f(void)
{
client_t *client;
client_t *save;
int j;
char *p;
char text[64];
char *tellmsg;
if (cmd_source == src_command)
{
Cmd_ForwardToServer();
return;
}
if (Cmd_Argc() < 3)
return;
p = (char *)Cmd_Args();
if (!p)
return;
Q_snprintf(text, sizeof(text), "%s TELL: ", host_client->name);
if (*p == '"')
{
p++;
p[Q_strlen(p) - 1] = 0;
}
j = ARRAYSIZE(text) - 2 - Q_strlen(text);
if (Q_strlen(p) > (unsigned int)j)
p[j] = 0;
tellmsg = Q_strstr(p, Cmd_Argv(1));
if (tellmsg != NULL)
Q_strcat(text, &tellmsg[Q_strlen(Cmd_Argv(1))]);
else
Q_strcat(text, p);
Q_strcat(text, "\n");
save = host_client;
for (j = 0, client = g_psvs.clients; j < g_psvs.maxclients; j++, client++)
{
if (!client->active || !client->spawned || client->fakeclient)
continue;
if (Q_stricmp(client->name,Cmd_Argv(1)))
continue;
host_client = client;
PF_MessageBegin_I(MSG_ONE, RegUserMsg("SayText", -1), NULL, &g_psv.edicts[j + 1]);
PF_WriteByte_I(0);
PF_WriteString_I(text);
PF_MessageEnd_I();
break;
}
host_client = save;
}
/* <3d4a6> ../engine/host_cmd.c:3625 */
void Host_Kill_f(void)
{
if (cmd_source == src_command)
{
Cmd_ForwardToServer();
return;
}
if (sv_player->v.health <= 0.0f)
{
SV_ClientPrintf("Can't suicide -- already dead!\n");
return;
}
gGlobalVariables.time = g_psv.time;
gEntityInterface.pfnClientKill(sv_player);
}
/* <3db79> ../engine/host_cmd.c:3647 */
void Host_TogglePause_f(void)
{
if (cmd_source == src_command)
{
Cmd_ForwardToServer();
return;
}
if (!pausable.value)
{
SV_ClientPrintf("Pause not allowed.\n");
return;
}
g_psv.paused ^= TRUE;
if (g_psv.paused)
SV_BroadcastPrintf("%s paused the game\n", &pr_strings[sv_player->v.netname]);
else
SV_BroadcastPrintf("%s unpaused the game\n", &pr_strings[sv_player->v.netname]);
MSG_WriteByte(&g_psv.reliable_datagram, svc_setpause);
MSG_WriteByte(&g_psv.reliable_datagram, g_psv.paused);
}
/* <3d49b> ../engine/host_cmd.c:3679 */
void Host_Pause_f(void)
{
// pause only singleplayer when console or main menu opens
if (!g_pcl.levelname[0])
return;
if (cmd_source == src_command)
{
Cmd_ForwardToServer();
return;
}
if (!pausable.value)
return;
g_psv.paused = TRUE;
MSG_WriteByte(&g_psv.reliable_datagram, svc_setpause);
MSG_WriteByte(&g_psv.reliable_datagram, g_psv.paused);
}
/* <3d490> ../engine/host_cmd.c:3707 */
void Host_Unpause_f(void)
{
// unpause only singleplayer when console or main menu opens
if (!g_pcl.levelname[0])
return;
if (cmd_source == src_command)
{
Cmd_ForwardToServer();
return;
}
if (!pausable.value)
return;
g_psv.paused = FALSE;
MSG_WriteByte(&g_psv.reliable_datagram, svc_setpause);
MSG_WriteByte(&g_psv.reliable_datagram, g_psv.paused);
}
/* <3db08> ../engine/host_cmd.c:3873 */
void Host_Interp_f(void)
{
r_dointerp ^= 1;
if(!r_dointerp)
Con_Printf("Frame Interpolation OFF\n");
else
Con_Printf("Frame Interpolation ON\n");
}
/* <400f8> ../engine/host_cmd.c:3898 */
void Host_NextDemo(void)
{
char str[1024];
if (g_pcls.demonum == -1)
return;
SCR_BeginLoadingPlaque(FALSE);
if (g_pcls.demos[g_pcls.demonum][0])
{
#ifdef REHLDS_FIXES
if (g_pcls.demonum >= MAX_DEMOS)
#else
if (g_pcls.demonum == MAX_DEMOS)
#endif // REHLDS_FIXES
g_pcls.demonum = 0;
Q_snprintf(str, sizeof(str), "playdemo %s\n", g_pcls.demos[g_pcls.demonum]);
Cbuf_InsertText(str);
++g_pcls.demonum;
}
Con_Printf("No demos listed with startdemos\n");
g_pcls.demonum = -1;
}
/* <3d8c4> ../engine/host_cmd.c:3929 */
void Host_Startdemos_f(void)
{
int i;
int c;
if (g_pcls.state == ca_dedicated)
{
if (!g_psv.active)
Con_Printf("Cannot play demos on a dedicated server.\n");
return;
}
c = Cmd_Argc() - 1;
if (c > MAX_DEMOS)
{
c = MAX_DEMOS;
Con_Printf("Max %i demos in demoloop\n", MAX_DEMOS);
Con_Printf("%i demo(s) in loop\n", MAX_DEMOS);
}
Con_Printf("%i demo(s) in loop\n", c);
for (i = 1; i < c + 1; i++)
{
Q_strncpy(g_pcls.demos[i - 1], Cmd_Argv(i), 15);
g_pcls.demos[i - 1][15] = 0;
}
if (g_psv.active || g_pcls.demonum == -1 || g_pcls.demoplayback)
g_pcls.demonum = -1;
else
{
g_pcls.demonum = 0;
Host_NextDemo();
}
}
/* <3d8b9> ../engine/host_cmd.c:3972 */
void Host_Demos_f(void)
{
if (g_pcls.state != ca_dedicated)
{
if (g_pcls.demonum == -1)
g_pcls.demonum = 0;
CL_Disconnect_f();
Host_NextDemo();
}
}
/* <3d485> ../engine/host_cmd.c:3989 */
void Host_Stopdemo_f(void)
{
if (g_pcls.state != ca_dedicated)
{
if (g_pcls.demoplayback)
{
CL_StopPlayback();
CL_Disconnect();
}
}
}
/* <401a6> ../engine/host_cmd.c:4009 */
NOXREF void Host_EndSection(const char *pszSection)
{
giActive = DLL_PAUSED;
giSubState = 1;
giStateInfo = 1;
if (!pszSection || !*pszSection)
Con_Printf(" endsection with no arguments\n");
else
{
if (!Q_stricmp(pszSection, "_oem_end_training"))
giStateInfo = 1;
else if (!Q_stricmp(pszSection, "_oem_end_logo"))
giStateInfo = 2;
else if (!Q_stricmp(pszSection, "_oem_end_demo"))
giStateInfo = 3;
else
Con_DPrintf(" endsection with unknown Section keyvalue\n");
}
Cbuf_AddText("\ndisconnect\n");
}
/* <3db1e> ../engine/host_cmd.c:4050 */
void Host_Soundfade_f(void)
{
int percent;
int inTime;
int holdTime;
int outTime;
if (Cmd_Argc() != 3 && Cmd_Argc() != 5)
{
Con_Printf("soundfade <percent> <hold> [<out> <int>]\n");
return;
}
percent = Q_atoi(Cmd_Argv(1));
if (percent > 100)
percent = 100;
if (percent < 0)
percent = 0;
holdTime = Q_atoi(Cmd_Argv(2));
if (holdTime > 255)
holdTime = 255;
if (Cmd_Argc() == 5)
{
outTime = Q_atoi(Cmd_Argv(3));
if (outTime > 255)
outTime = 255;
inTime = Q_atoi(Cmd_Argv(4));
if (inTime > 255)
inTime = 255;
}
else
{
outTime = 0;
inTime = 0;
}
g_pcls.soundfade.nStartPercent = percent;
g_pcls.soundfade.soundFadeStartTime = realtime;
g_pcls.soundfade.soundFadeOutTime = outTime;
g_pcls.soundfade.soundFadeHoldTime = holdTime;
g_pcls.soundfade.soundFadeInTime = inTime;
}
/* <3daf2> ../engine/host_cmd.c:4095 */
void Host_KillServer_f(void)
{
if (g_pcls.state != ca_dedicated)
CL_Disconnect_f();
else if (g_psv.active)
{
Host_ShutdownServer(FALSE);
if (g_pcls.state != ca_dedicated)
NET_Config(FALSE);
}
}
/* <401d0> ../engine/host_cmd.c:4110 */
void Host_VoiceRecordStart_f(void)
{
const char *pUncompressedFile = NULL;
const char *pDecompressedFile = NULL;
const char *pInputFile = NULL;
if (g_pcls.state != ca_active)
return;
if (voice_recordtofile.value)
{
pDecompressedFile = "voice_decompressed.wav";
pUncompressedFile = "voice_micdata.wav";
}
if (voice_inputfromfile.value)
pInputFile = "voice_input.wav";
Voice_RecordStart(pUncompressedFile, pDecompressedFile, pInputFile);
}
/* <40225> ../engine/host_cmd.c:4136 */
void Host_VoiceRecordStop_f(void)
{
if (g_pcls.state != ca_active)
return;
if (Voice_IsRecording())
{
CL_AddVoiceToDatagram(TRUE);
Voice_RecordStop();
}
}
/* <4023b> ../engine/host_cmd.c:4230 */
void Host_Crash_f(void)
{
int *p = NULL;
*p = 0xffffffff;
}
/* <40260> ../engine/host_cmd.c:4242 */
void Host_InitCommands(void)
{
#ifdef HOOK_ENGINE
Cmd_AddCommand("shutdownserver", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_KillServer_f", (void *)Host_KillServer_f));
Cmd_AddCommand("soundfade", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Soundfade_f", (void *)Host_Soundfade_f));
Cmd_AddCommand("status", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Status_f", (void *)Host_Status_f));
Cmd_AddCommand("stat", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Status_Formatted_f", (void *)Host_Status_Formatted_f));
Cmd_AddCommand("quit", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Quit_f", (void *)Host_Quit_f));
Cmd_AddCommand("_restart", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Quit_Restart_f", (void *)Host_Quit_Restart_f));
Cmd_AddCommand("exit", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Quit_f", (void *)Host_Quit_f));
Cmd_AddCommand("map", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Map_f", (void *)Host_Map_f));
Cmd_AddCommand("career", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Career_f", (void *)Host_Career_f));
Cmd_AddCommand("maps", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Maps_f", (void *)Host_Maps_f));
Cmd_AddCommand("restart", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Restart_f", (void *)Host_Restart_f));
Cmd_AddCommand("reload", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Reload_f", (void *)Host_Reload_f));
Cmd_AddCommand("changelevel", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Changelevel_f", (void *)Host_Changelevel_f));
Cmd_AddCommand("changelevel2", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Changelevel2_f", (void *)Host_Changelevel2_f));
Cmd_AddCommand("reconnect", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Reconnect_f", (void *)Host_Reconnect_f));
Cmd_AddCommand("version", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Version_f", (void *)Host_Version_f));
Cmd_AddCommand("say", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Say_f", (void *)Host_Say_f));
Cmd_AddCommand("say_team", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Say_Team_f", (void *)Host_Say_Team_f));
Cmd_AddCommand("tell", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Tell_f", (void *)Host_Tell_f));
Cmd_AddCommand("kill", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Kill_f", (void *)Host_Kill_f));
Cmd_AddCommand("pause", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_TogglePause_f", (void *)Host_TogglePause_f));
Cmd_AddCommand("setpause", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Pause_f", (void *)Host_Pause_f));
Cmd_AddCommand("unpause", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Unpause_f", (void *)Host_Unpause_f));
Cmd_AddCommand("kick", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Kick_f", (void *)Host_Kick_f));
Cmd_AddCommand("ping", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Ping_f", (void *)Host_Ping_f));
Cmd_AddCommand("motd", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Motd_f", (void *)Host_Motd_f));
Cmd_AddCommand("motd_write", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Motd_Write_f", (void *)Host_Motd_Write_f));
Cmd_AddCommand("stats", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Stats_f", (void *)Host_Stats_f));
Cmd_AddCommand("load", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Loadgame_f", (void *)Host_Loadgame_f));
Cmd_AddCommand("save", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Savegame_f", (void *)Host_Savegame_f));
Cmd_AddCommand("autosave", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_AutoSave_f", (void *)Host_AutoSave_f));
Cmd_AddCommand("writecfg", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_WriteCustomConfig", (void *)Host_WriteCustomConfig));
Cmd_AddCommand("startdemos", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Startdemos_f", (void *)Host_Startdemos_f));
Cmd_AddCommand("demos", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Demos_f", (void *)Host_Demos_f));
Cmd_AddCommand("stopdemo", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Stopdemo_f", (void *)Host_Stopdemo_f));
Cmd_AddCommand("setinfo", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_SetInfo_f", (void *)Host_SetInfo_f));
Cmd_AddCommand("fullinfo", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_FullInfo_f", (void *)Host_FullInfo_f));
Cmd_AddCommand("mcache", (xcommand_t)GetOriginalFuncAddrOrDefault("Mod_Print", (void *)Mod_Print));
Cmd_AddCommand("interp", (xcommand_t)GetOriginalFuncAddrOrDefault("Host_Interp_f", (void *)Host_Interp_f));
Cmd_AddCommand("setmaster", (xcommand_t)GetOriginalFuncAddrOrDefault("Master_SetMaster_f", (void *)Master_SetMaster_f));
Cmd_AddCommand("heartbeat", (xcommand_t)GetOriginalFuncAddrOrDefault("Master_Heartbeat_f", (void *)Master_Heartbeat_f));
#else // HOOK_ENGINE
#ifndef SWDS
Cmd_AddCommand("cd", CD_Command_f);
Cmd_AddCommand("mp3", MP3_Command_f);
Cmd_AddCommand("_careeraudio", CareerAudio_Command_f);
#endif // SWDS
Cmd_AddCommand("shutdownserver", Host_KillServer_f);
Cmd_AddCommand("soundfade", Host_Soundfade_f);
Cmd_AddCommand("status", Host_Status_f);
Cmd_AddCommand("stat", Host_Status_Formatted_f);
Cmd_AddCommand("quit", Host_Quit_f);
Cmd_AddCommand("_restart", Host_Quit_Restart_f);
#ifndef SWDS
Cmd_AddCommand("_setrenderer", Host_SetRenderer_f);
Cmd_AddCommand("_setvideomode", Host_SetVideoMode_f);
Cmd_AddCommand("_setgamedir", Host_SetGameDir_f);
Cmd_AddCommand("_sethdmodels", Host_SetHDModels_f);
Cmd_AddCommand("_setaddons_folder", Host_SetAddonsFolder_f);
Cmd_AddCommand("_set_vid_level", Host_SetVideoLevel_f);
#endif // SWDS
Cmd_AddCommand("exit", Host_Quit_f);
Cmd_AddCommand("map", Host_Map_f);
Cmd_AddCommand("career", Host_Career_f);
Cmd_AddCommand("maps", Host_Maps_f);
Cmd_AddCommand("restart", Host_Restart_f);
Cmd_AddCommand("reload", Host_Reload_f);
Cmd_AddCommand("changelevel", Host_Changelevel_f);
Cmd_AddCommand("changelevel2", Host_Changelevel2_f);
Cmd_AddCommand("reconnect", Host_Reconnect_f);
Cmd_AddCommand("version", Host_Version_f);
Cmd_AddCommand("say", Host_Say_f);
Cmd_AddCommand("say_team", Host_Say_Team_f);
Cmd_AddCommand("tell", Host_Tell_f);
Cmd_AddCommand("kill", Host_Kill_f);
Cmd_AddCommand("pause", Host_TogglePause_f);
Cmd_AddCommand("setpause", Host_Pause_f);
Cmd_AddCommand("unpause", Host_Unpause_f);
Cmd_AddCommand("kick", Host_Kick_f);
Cmd_AddCommand("ping", Host_Ping_f);
Cmd_AddCommand("motd", Host_Motd_f);
Cmd_AddCommand("motd_write", Host_Motd_Write_f);
Cmd_AddCommand("stats", Host_Stats_f);
Cmd_AddCommand("load", Host_Loadgame_f);
Cmd_AddCommand("save", Host_Savegame_f);
Cmd_AddCommand("autosave", Host_AutoSave_f);
Cmd_AddCommand("writecfg", Host_WriteCustomConfig);
#ifndef SWDS
Cmd_AddCommand("+voicerecord", Host_VoiceRecordStart_f);
Cmd_AddCommand("-voicerecord", Host_VoiceRecordStop_f);
#endif // SWDS
Cmd_AddCommand("startdemos", Host_Startdemos_f);
Cmd_AddCommand("demos", Host_Demos_f);
Cmd_AddCommand("stopdemo", Host_Stopdemo_f);
Cmd_AddCommand("setinfo", Host_SetInfo_f);
Cmd_AddCommand("fullinfo", Host_FullInfo_f);
#ifndef SWDS
Cmd_AddCommand("god", Host_God_f);
Cmd_AddCommand("notarget", Host_Notarget_f);
Cmd_AddCommand("fly", Host_Fly_f);
Cmd_AddCommand("noclip", Host_Noclip_f);
Cmd_AddCommand("viewmodel", Host_Viewmodel_f);
Cmd_AddCommand("viewframe", Host_Viewframe_f);
Cmd_AddCommand("viewnext", Host_Viewnext_f);
Cmd_AddCommand("viewprev", Host_Viewprev_f);
#endif // SWDS
Cmd_AddCommand("mcache", Mod_Print);
Cmd_AddCommand("interp", Host_Interp_f);
Cmd_AddCommand("setmaster", Master_SetMaster_f);
Cmd_AddCommand("heartbeat", Master_Heartbeat_f);
#endif // HOOK_ENGINE
Cvar_RegisterVariable(&gHostMap);
Cvar_RegisterVariable(&voice_recordtofile);
Cvar_RegisterVariable(&voice_inputfromfile);
}
/* <40276> ../engine/host_cmd.c:4388 */
void SV_CheckBlendingInterface(void)
{
int i;
SV_BLENDING_INTERFACE_FUNC studio_interface;
R_ResetSvBlending();
for (i = 0; i < g_iextdllMac; i++)
{
#ifdef _WIN32
studio_interface = (SV_BLENDING_INTERFACE_FUNC)GetProcAddress((HMODULE)g_rgextdll[i].lDLLHandle, "Server_GetBlendingInterface");
#else
studio_interface = (SV_BLENDING_INTERFACE_FUNC)dlsym(g_rgextdll[i].lDLLHandle, "Server_GetBlendingInterface");
#endif // _WIN32
if (studio_interface)
{
if (studio_interface(SV_BLENDING_INTERFACE_VERSION, &g_pSvBlendingAPI, &server_studio_api, (float *)rotationmatrix, (float *)bonetransform))
return;
Con_DPrintf("Couldn't get server .dll studio model blending interface. Version mismatch?\n");
R_ResetSvBlending();
}
}
}
/* <3e266> ../engine/host_cmd.c:4431 */
void SV_CheckSaveGameCommentInterface(void)
{
int i;
SV_SAVEGAMECOMMENT_FUNC pTemp = NULL;
for (i = 0; i < g_iextdllMac; i++)
{
#ifdef _WIN32
pTemp = (SV_SAVEGAMECOMMENT_FUNC)GetProcAddress((HMODULE)g_rgextdll[i].lDLLHandle, "SV_SaveGameComment");
#else
pTemp = (SV_SAVEGAMECOMMENT_FUNC)dlsym(g_rgextdll[i].lDLLHandle, "SV_SaveGameComment");
#endif // _WIN32
if (pTemp)
break;
}
g_pSaveGameCommentFunc = pTemp;
}