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 model
[MAXLENGTH_MODELPATH
];
57 char bmp
[MAXLENGTH_MODELPATH
];
61 char playername
[MAXLENGTH_PLAYERNAME
];
62 char modelname
[MAXLENGTH_MODELNAME
];
66 #define MAX_PRECACHE_COUNT 32
67 precache_entry precache_list
[MAX_PRECACHE_COUNT
];
68 unsigned short int precache_count
= 0;
70 bool fileExists(const char* path
) {
72 snprintf(fullpath
, sizeof(fullpath
), "%s/%s", &gGamedir
[0], path
);
73 return access(fullpath
, R_OK
) == 0;
76 bool addPrecacheEntry(const char* playername
, const char* model
) {
79 while ((i
< precache_count
) && ((streq
= strcmp(precache_list
[i
].modelname
, model
)) != 0)) i
++;
80 if ((i
== precache_count
) && (i
< MAX_PRECACHE_COUNT
) && (streq
!= 0)) {
81 strncpy(precache_list
[i
].playername
, playername
, MAXLENGTH_PLAYERNAME
- 1);
82 strncpy(precache_list
[i
].modelname
, model
, MAXLENGTH_MODELNAME
- 1);
83 // Ensure null-termination
84 precache_list
[i
].playername
[MAXLENGTH_PLAYERNAME
- 1] = 0;
85 precache_list
[i
].modelname
[MAXLENGTH_MODELNAME
- 1] = 0;
87 snprintf(precache_list
[i
].paths
.model
, MAXLENGTH_MODELPATH
, "models/player/%s/%s.mdl", model
, model
);
88 snprintf(precache_list
[i
].paths
.bmp
, MAXLENGTH_MODELPATH
, "models/player/%s/%s.bmp", model
, model
);
91 LOG_MESSAGE(PLID
, "Precache entry %d: playername=\"%s\" modelname=\"%s\" paths.model=\"%s\" paths.bmp=\"%s\"", i
, precache_list
[i
].playername
, precache_list
[i
].modelname
, precache_list
[i
].paths
.model
, precache_list
[i
].paths
.bmp
);
98 void ClientPutInServer( edict_t
*pEntity
) {
99 const char* playername
= STRING(pEntity
->v
.netname
);
100 char* modelname
= g_engfuncs
.pfnInfoKeyValue( g_engfuncs
.pfnGetInfoKeyBuffer( pEntity
), "model" );
102 snprintf(modelfile
, sizeof(modelfile
), "models/player/%s/%s.mdl", modelname
, modelname
);
103 LOG_MESSAGE(PLID
, "Player %s is using model %s", playername
, modelname
);
104 if (fileExists( modelfile
)) {
105 LOG_MESSAGE(PLID
, "Model %s is present on server", modelname
);
106 SAY(pEntity
, "Your model is present on the server, it will be precached for the next round!");
107 if (addPrecacheEntry( playername
, modelname
))
108 LOG_MESSAGE(PLID
, "Added model %s to precache list", modelname
);
110 LOG_MESSAGE(PLID
, "Model %s will not be precached - reduntant or precache list is full", modelname
);
113 LOG_MESSAGE(PLID
, "Unable to precache due to FILE MISSING: %s!", modelfile
);
114 SAY(pEntity
, "Your model is not present on the server, can't distribute for other players!");
116 RETURN_META(MRES_IGNORED
);
119 void ServerActivate(edict_t
*pEdictList
, int edictCount
, int clientMax
) {
120 LOG_MESSAGE(PLID
, "Precaching %d player models", precache_count
);
121 for (int i
= 0; i
< precache_count
; i
++) {
122 LOG_MESSAGE(PLID
, "Precaching model: %s (contributed by %s)", precache_list
[i
].modelname
, precache_list
[i
].playername
);
123 g_engfuncs
.pfnPrecacheModel( precache_list
[i
].paths
.model
);
124 if (fileExists( precache_list
[i
].paths
.bmp
))
126 LOG_MESSAGE(PLID
, "Precaching bmp: %s", precache_list
[i
].paths
.bmp
);
127 g_engfuncs
.pfnPrecacheGeneric( precache_list
[i
].paths
.bmp
);
130 LOG_MESSAGE(PLID
, "File not found: %s", precache_list
[i
].paths
.bmp
);
133 RETURN_META(MRES_HANDLED
);
136 static DLL_FUNCTIONS gFunctionTable
=
147 NULL
, // pfnSetAbsBox
149 NULL
, // pfnSaveWriteFields
150 NULL
, // pfnSaveReadFields
152 NULL
, // pfnSaveGlobalState
153 NULL
, // pfnRestoreGlobalState
154 NULL
, // pfnResetGlobalState
156 NULL
, // pfnClientConnect
157 NULL
, // pfnClientDisconnect
158 NULL
, // pfnClientKill
159 ClientPutInServer
, // pfnClientPutInServer
160 NULL
, // pfnClientCommand
161 NULL
, // pfnClientUserInfoChanged
162 ServerActivate
, // pfnServerActivate
163 NULL
, // pfnServerDeactivate
165 NULL
, // pfnPlayerPreThink
166 NULL
, // pfnPlayerPostThink
168 NULL
, // pfnStartFrame
169 NULL
, // pfnParmsNewLevel
170 NULL
, // pfnParmsChangeLevel
172 NULL
, // pfnGetGameDescription
173 NULL
, // pfnPlayerCustomization
175 NULL
, // pfnSpectatorConnect
176 NULL
, // pfnSpectatorDisconnect
177 NULL
, // pfnSpectatorThink
179 NULL
, // pfnSys_Error
183 NULL
, // pfnPM_FindTextureType
185 NULL
, // pfnSetupVisibility
186 NULL
, // pfnUpdateClientData
187 NULL
, // pfnAddToFullPack
188 NULL
, // pfnCreateBaseline
189 NULL
, // pfnRegisterEncoders
190 NULL
, // pfnGetWeaponData
193 NULL
, // pfnConnectionlessPacket
194 NULL
, // pfnGetHullBounds
195 NULL
, // pfnCreateInstancedBaselines
196 NULL
, // pfnInconsistentFile
197 NULL
, // pfnAllowLagCompensation
200 C_DLLEXPORT
int GetEntityAPI2(DLL_FUNCTIONS
*pFunctionTable
,
201 int *interfaceVersion
)
203 if(!pFunctionTable
) {
204 UTIL_LogPrintf("GetEntityAPI2 called with null pFunctionTable");
207 else if(*interfaceVersion
!= INTERFACE_VERSION
) {
208 UTIL_LogPrintf("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion
, INTERFACE_VERSION
);
209 //! Tell metamod what version we had, so it can figure out who is out of date.
210 *interfaceVersion
= INTERFACE_VERSION
;
213 memcpy(pFunctionTable
, &gFunctionTable
, sizeof(DLL_FUNCTIONS
));