5 * Copyright (c) 2001-2003 Will Day <willday@hpgx.net>
7 * This file is part of Metamod.
9 * Metamod is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
14 * Metamod is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Metamod; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * In addition, as a special exception, the author gives permission to
24 * link the code of this program with the Half-Life Game Engine ("HL
25 * Engine") and Modified Game Libraries ("MODs") developed by Valve,
26 * L.L.C ("Valve"). You must obey the GNU General Public License in all
27 * respects for all of the code used other than the HL Engine and MODs
28 * from Valve. If you modify this file, you may extend this exception
29 * to your version of the file, but you are not obligated to do so. If
30 * you do not wish to do so, delete this exception statement from your
42 #define SAY(pEntity, text) {\
43 MESSAGE_BEGIN( MSG_ONE, GET_USER_MSG_ID(PLID, "SayText", NULL), NULL, pEntity );\
44 WRITE_BYTE( ENTINDEX(pEntity) );\
45 WRITE_STRING( text );\
49 extern char gGamedir
[];
52 #define MAXLENGTH_PLAYERNAME 64
53 #define MAXLENGTH_MODELNAME 64
54 #define MAXLENGTH_MODELPATH 256
56 char playername
[MAXLENGTH_PLAYERNAME
];
57 char modelname
[MAXLENGTH_MODELNAME
];
58 char modelpath
[MAXLENGTH_MODELPATH
];
61 #define MAX_PRECACHE_COUNT 32
62 precache_entry precache_list
[MAX_PRECACHE_COUNT
];
63 unsigned short int precache_count
= 0;
65 bool playerModelFileExists(const char* path
) {
66 return access(path
, R_OK
) == 0;
69 bool addPrecacheEntry(const char* playername
, const char* model
) {
72 while ((i
< precache_count
) && ((streq
= strcmp(precache_list
[i
].modelname
, model
)) != 0)) i
++;
73 if ((i
== precache_count
) && (i
< MAX_PRECACHE_COUNT
) && (streq
!= 0)) {
74 strncpy(precache_list
[i
].playername
, playername
, MAXLENGTH_PLAYERNAME
- 1);
75 strncpy(precache_list
[i
].modelname
, model
, MAXLENGTH_MODELNAME
- 1);
76 snprintf(precache_list
[i
].modelpath
, MAXLENGTH_MODELPATH
, "models/player/%s/%s.mdl", model
, model
);
77 precache_list
[i
].playername
[MAXLENGTH_PLAYERNAME
- 1] = 0;
78 precache_list
[i
].modelname
[MAXLENGTH_MODELNAME
- 1] = 0;
80 LOG_MESSAGE(PLID
, "Precache entry %d: playername=\"%s\" modelname=\"%s\" modelpath=\"%s\"", i
, precache_list
[i
].playername
, precache_list
[i
].modelname
, precache_list
[i
].modelpath
);
87 void ClientPutInServer( edict_t
*pEntity
) {
88 const char* playername
= STRING(pEntity
->v
.netname
);
89 char* modelname
= g_engfuncs
.pfnInfoKeyValue( g_engfuncs
.pfnGetInfoKeyBuffer( pEntity
), "model" );
91 snprintf(modelfile
, sizeof(modelfile
), "%s/models/player/%s/%s.mdl", &gGamedir
[0], modelname
, modelname
);
92 LOG_MESSAGE(PLID
, "Player %s is using model %s", playername
, modelname
);
93 if (playerModelFileExists( modelfile
)) {
94 LOG_MESSAGE(PLID
, "Model %s is present on server", modelname
);
95 SAY(pEntity
, "Your model is present on the server, it will be precached for the next round!");
96 if (addPrecacheEntry( playername
, modelname
))
97 LOG_MESSAGE(PLID
, "Added model %s to precache list", modelname
);
99 LOG_MESSAGE(PLID
, "Model %s will not be precached - reduntant or precache list is full", modelname
);
102 LOG_MESSAGE(PLID
, "Unable to precache due to FILE MISSING: %s!", modelfile
);
103 SAY(pEntity
, "Your model is not present on the server, can't distribute for other players!");
105 RETURN_META(MRES_IGNORED
);
108 void ServerActivate(edict_t
*pEdictList
, int edictCount
, int clientMax
) {
109 LOG_MESSAGE(PLID
, "Precaching %d player models", precache_count
);
110 for (int i
= 0; i
< precache_count
; i
++) {
111 LOG_MESSAGE(PLID
, "Precaching model: %s (contributed by %s)", precache_list
[i
].modelname
, precache_list
[i
].playername
);
112 LOG_MESSAGE(PLID
, "modelpath = %s", precache_list
[i
].modelpath
);
113 g_engfuncs
.pfnPrecacheModel( precache_list
[i
].modelpath
);
116 RETURN_META(MRES_HANDLED
);
119 static DLL_FUNCTIONS gFunctionTable
=
130 NULL
, // pfnSetAbsBox
132 NULL
, // pfnSaveWriteFields
133 NULL
, // pfnSaveReadFields
135 NULL
, // pfnSaveGlobalState
136 NULL
, // pfnRestoreGlobalState
137 NULL
, // pfnResetGlobalState
139 NULL
, // pfnClientConnect
140 NULL
, // pfnClientDisconnect
141 NULL
, // pfnClientKill
142 ClientPutInServer
, // pfnClientPutInServer
143 NULL
, // pfnClientCommand
144 NULL
, // pfnClientUserInfoChanged
145 ServerActivate
, // pfnServerActivate
146 NULL
, // pfnServerDeactivate
148 NULL
, // pfnPlayerPreThink
149 NULL
, // pfnPlayerPostThink
151 NULL
, // pfnStartFrame
152 NULL
, // pfnParmsNewLevel
153 NULL
, // pfnParmsChangeLevel
155 NULL
, // pfnGetGameDescription
156 NULL
, // pfnPlayerCustomization
158 NULL
, // pfnSpectatorConnect
159 NULL
, // pfnSpectatorDisconnect
160 NULL
, // pfnSpectatorThink
162 NULL
, // pfnSys_Error
166 NULL
, // pfnPM_FindTextureType
168 NULL
, // pfnSetupVisibility
169 NULL
, // pfnUpdateClientData
170 NULL
, // pfnAddToFullPack
171 NULL
, // pfnCreateBaseline
172 NULL
, // pfnRegisterEncoders
173 NULL
, // pfnGetWeaponData
176 NULL
, // pfnConnectionlessPacket
177 NULL
, // pfnGetHullBounds
178 NULL
, // pfnCreateInstancedBaselines
179 NULL
, // pfnInconsistentFile
180 NULL
, // pfnAllowLagCompensation
183 C_DLLEXPORT
int GetEntityAPI2(DLL_FUNCTIONS
*pFunctionTable
,
184 int *interfaceVersion
)
186 if(!pFunctionTable
) {
187 UTIL_LogPrintf("GetEntityAPI2 called with null pFunctionTable");
190 else if(*interfaceVersion
!= INTERFACE_VERSION
) {
191 UTIL_LogPrintf("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion
, INTERFACE_VERSION
);
192 //! Tell metamod what version we had, so it can figure out who is out of date.
193 *interfaceVersion
= INTERFACE_VERSION
;
196 memcpy(pFunctionTable
, &gFunctionTable
, sizeof(DLL_FUNCTIONS
));