1#include "antibot.h"
2
3#include <antibot/antibot_interface.h>
4
5#include <base/system.h>
6
7#include <engine/console.h>
8#include <engine/kernel.h>
9#include <engine/server.h>
10
11class IEngineAntibot;
12
13#ifdef CONF_ANTIBOT
14CAntibot::CAntibot() :
15 m_pServer(0), m_pConsole(0), m_pGameServer(0), m_Initialized(false)
16{
17}
18CAntibot::~CAntibot()
19{
20 if(m_pGameServer)
21 free(m_RoundData.m_Map.m_pTiles);
22
23 if(m_Initialized)
24 AntibotDestroy();
25}
26void CAntibot::Kick(int ClientId, const char *pMessage, void *pUser)
27{
28 CAntibot *pAntibot = (CAntibot *)pUser;
29 pAntibot->Server()->Kick(ClientId, pMessage);
30}
31void CAntibot::Log(const char *pMessage, void *pUser)
32{
33 CAntibot *pAntibot = (CAntibot *)pUser;
34 pAntibot->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "antibot", pMessage);
35}
36void CAntibot::Report(int ClientId, const char *pMessage, void *pUser)
37{
38 char aBuf[256];
39 str_format(aBuf, sizeof(aBuf), "%d: %s", ClientId, pMessage);
40 Log(aBuf, pUser);
41}
42void CAntibot::Send(int ClientId, const void *pData, int Size, int Flags, void *pUser)
43{
44 CAntibot *pAntibot = (CAntibot *)pUser;
45
46 int RealFlags = MSGFLAG_VITAL;
47 if(Flags & ANTIBOT_MSGFLAG_NONVITAL)
48 {
49 RealFlags &= ~MSGFLAG_VITAL;
50 }
51 if(Flags & ANTIBOT_MSGFLAG_FLUSH)
52 {
53 RealFlags |= MSGFLAG_FLUSH;
54 }
55 pAntibot->Server()->SendMsgRaw(ClientId, pData, Size, RealFlags);
56}
57void CAntibot::Teehistorian(const void *pData, int Size, void *pUser)
58{
59 CAntibot *pAntibot = (CAntibot *)pUser;
60 pAntibot->m_pGameServer->TeehistorianRecordAntibot(pData, Size);
61}
62void CAntibot::Init()
63{
64 m_pServer = Kernel()->RequestInterface<IServer>();
65 m_pConsole = Kernel()->RequestInterface<IConsole>();
66 dbg_assert(m_pServer && m_pConsole, "antibot requires server and console");
67 dbg_assert(AntibotAbiVersion() == ANTIBOT_ABI_VERSION, "antibot abi version mismatch");
68
69 mem_zero(&m_Data, sizeof(m_Data));
70 CAntibotVersion Version = ANTIBOT_VERSION;
71 m_Data.m_Version = Version;
72
73 m_Data.m_Now = time_get();
74 m_Data.m_Freq = time_freq();
75 m_Data.m_pfnKick = Kick;
76 m_Data.m_pfnLog = Log;
77 m_Data.m_pfnReport = Report;
78 m_Data.m_pfnSend = Send;
79 m_Data.m_pfnTeehistorian = Teehistorian;
80 m_Data.m_pUser = this;
81 AntibotInit(&m_Data);
82
83 m_Initialized = true;
84}
85void CAntibot::RoundStart(IGameServer *pGameServer)
86{
87 m_pGameServer = pGameServer;
88 mem_zero(&m_RoundData, sizeof(m_RoundData));
89 m_RoundData.m_Map.m_pTiles = 0;
90 AntibotRoundStart(&m_RoundData);
91 Update();
92}
93void CAntibot::RoundEnd()
94{
95 // Let the external module clean up first
96 AntibotRoundEnd();
97
98 m_pGameServer = 0;
99 free(m_RoundData.m_Map.m_pTiles);
100}
101void CAntibot::ConsoleCommand(const char *pCommand)
102{
103 AntibotConsoleCommand(pCommand);
104}
105void CAntibot::Update()
106{
107 m_Data.m_Now = time_get();
108 m_Data.m_Freq = time_freq();
109
110 Server()->FillAntibot(&m_RoundData);
111 if(GameServer())
112 {
113 GameServer()->FillAntibot(&m_RoundData);
114 AntibotUpdateData();
115 }
116}
117
118void CAntibot::OnPlayerInit(int ClientId)
119{
120 Update();
121 AntibotOnPlayerInit(ClientId);
122}
123void CAntibot::OnPlayerDestroy(int ClientId)
124{
125 Update();
126 AntibotOnPlayerDestroy(ClientId);
127}
128void CAntibot::OnSpawn(int ClientId)
129{
130 Update();
131 AntibotOnSpawn(ClientId);
132}
133void CAntibot::OnHammerFireReloading(int ClientId)
134{
135 Update();
136 AntibotOnHammerFireReloading(ClientId);
137}
138void CAntibot::OnHammerFire(int ClientId)
139{
140 Update();
141 AntibotOnHammerFire(ClientId);
142}
143void CAntibot::OnHammerHit(int ClientId, int TargetId)
144{
145 Update();
146 AntibotOnHammerHit(ClientId, TargetId);
147}
148void CAntibot::OnDirectInput(int ClientId)
149{
150 Update();
151 AntibotOnDirectInput(ClientId);
152}
153void CAntibot::OnCharacterTick(int ClientId)
154{
155 Update();
156 AntibotOnCharacterTick(ClientId);
157}
158void CAntibot::OnHookAttach(int ClientId, bool Player)
159{
160 Update();
161 AntibotOnHookAttach(ClientId, Player);
162}
163
164void CAntibot::OnEngineTick()
165{
166 Update();
167 AntibotOnEngineTick();
168}
169void CAntibot::OnEngineClientJoin(int ClientId, bool Sixup)
170{
171 Update();
172 AntibotOnEngineClientJoin(ClientId, Sixup);
173}
174void CAntibot::OnEngineClientDrop(int ClientId, const char *pReason)
175{
176 Update();
177 AntibotOnEngineClientDrop(ClientId, pReason);
178}
179bool CAntibot::OnEngineClientMessage(int ClientId, const void *pData, int Size, int Flags)
180{
181 Update();
182 int AntibotFlags = 0;
183 if((Flags & MSGFLAG_VITAL) == 0)
184 {
185 AntibotFlags |= ANTIBOT_MSGFLAG_NONVITAL;
186 }
187 return AntibotOnEngineClientMessage(ClientId, pData, Size, AntibotFlags);
188}
189bool CAntibot::OnEngineServerMessage(int ClientId, const void *pData, int Size, int Flags)
190{
191 Update();
192 int AntibotFlags = 0;
193 if((Flags & MSGFLAG_VITAL) == 0)
194 {
195 AntibotFlags |= ANTIBOT_MSGFLAG_NONVITAL;
196 }
197 return AntibotOnEngineServerMessage(ClientId, pData, Size, AntibotFlags);
198}
199bool CAntibot::OnEngineSimulateClientMessage(int *pClientId, void *pBuffer, int BufferSize, int *pOutSize, int *pFlags)
200{
201 int AntibotFlags = 0;
202 bool Result = AntibotOnEngineSimulateClientMessage(pClientId, pBuffer, BufferSize, pOutSize, &AntibotFlags);
203 if(Result)
204 {
205 *pFlags = 0;
206 if((AntibotFlags & ANTIBOT_MSGFLAG_NONVITAL) == 0)
207 {
208 *pFlags |= MSGFLAG_VITAL;
209 }
210 }
211 return Result;
212}
213#else
214CAntibot::CAntibot() :
215 m_pServer(0), m_pConsole(0), m_pGameServer(0), m_Initialized(false)
216{
217}
218CAntibot::~CAntibot() = default;
219void CAntibot::Init()
220{
221 m_pServer = Kernel()->RequestInterface<IServer>();
222 m_pConsole = Kernel()->RequestInterface<IConsole>();
223 dbg_assert(m_pServer && m_pConsole, "antibot requires server and console");
224}
225void CAntibot::RoundStart(IGameServer *pGameServer)
226{
227 m_pGameServer = pGameServer;
228}
229void CAntibot::RoundEnd()
230{
231 m_pGameServer = 0;
232}
233void CAntibot::ConsoleCommand(const char *pCommand)
234{
235 if(str_comp(a: pCommand, b: "dump") == 0)
236 {
237 Console()->Print(Level: IConsole::OUTPUT_LEVEL_STANDARD, pFrom: "antibot", pStr: "antibot support not compiled in");
238 }
239 else
240 {
241 Console()->Print(Level: IConsole::OUTPUT_LEVEL_STANDARD, pFrom: "antibot", pStr: "unknown command");
242 }
243}
244void CAntibot::Update()
245{
246}
247
248void CAntibot::OnPlayerInit(int ClientId) {}
249void CAntibot::OnPlayerDestroy(int ClientId) {}
250void CAntibot::OnSpawn(int ClientId) {}
251void CAntibot::OnHammerFireReloading(int ClientId) {}
252void CAntibot::OnHammerFire(int ClientId) {}
253void CAntibot::OnHammerHit(int ClientId, int TargetId) {}
254void CAntibot::OnDirectInput(int ClientId) {}
255void CAntibot::OnCharacterTick(int ClientId) {}
256void CAntibot::OnHookAttach(int ClientId, bool Player) {}
257
258void CAntibot::OnEngineTick() {}
259void CAntibot::OnEngineClientJoin(int ClientId, bool Sixup) {}
260void CAntibot::OnEngineClientDrop(int ClientId, const char *pReason) {}
261bool CAntibot::OnEngineClientMessage(int ClientId, const void *pData, int Size, int Flags) { return false; }
262bool CAntibot::OnEngineServerMessage(int ClientId, const void *pData, int Size, int Flags) { return false; }
263bool CAntibot::OnEngineSimulateClientMessage(int *pClientId, void *pBuffer, int BufferSize, int *pOutSize, int *pFlags) { return false; }
264#endif
265
266IEngineAntibot *CreateEngineAntibot()
267{
268 return new CAntibot;
269}
270