1 #include <engine/console.h>
2 #include <engine/shared/config.h>
6 int CEcon::NewClientCallback(int ClientID
, void *pUser
)
8 CEcon
*pThis
= (CEcon
*)pUser
;
10 NETADDR Addr
= pThis
->m_NetConsole
.ClientAddr(ClientID
);
11 char aAddrStr
[NETADDR_MAXSTRSIZE
];
12 net_addr_str(&Addr
, aAddrStr
, sizeof(aAddrStr
));
14 str_format(aBuf
, sizeof(aBuf
), "client accepted. cid=%d addr=%s'", ClientID
, aAddrStr
);
15 pThis
->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO
, "econ", aBuf
);
17 pThis
->m_aClients
[ClientID
].m_State
= CClient::STATE_CONNECTED
;
18 pThis
->m_aClients
[ClientID
].m_TimeConnected
= time_get();
22 int CEcon::DelClientCallback(int ClientID
, const char *pReason
, void *pUser
)
24 CEcon
*pThis
= (CEcon
*)pUser
;
26 NETADDR Addr
= pThis
->m_NetConsole
.ClientAddr(ClientID
);
27 char aAddrStr
[NETADDR_MAXSTRSIZE
];
28 net_addr_str(&Addr
, aAddrStr
, sizeof(aAddrStr
));
30 str_format(aBuf
, sizeof(aBuf
), "client dropped. cid=%d addr=%s reason='%s'", ClientID
, aAddrStr
, pReason
);
31 pThis
->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO
, "econ", aBuf
);
33 pThis
->m_aClients
[ClientID
].m_State
= CClient::STATE_EMPTY
;
37 void CEcon::SendLineCB(const char *pLine
, void *pUserData
)
39 static_cast<CEcon
*>(pUserData
)->Send(-1, pLine
);
42 void CEcon::ConchainEconOutputLevelUpdate(IConsole::IResult
*pResult
, void *pUserData
, IConsole::FCommandCallback pfnCallback
, void *pCallbackUserData
)
44 pfnCallback(pResult
, pCallbackUserData
);
45 if(pResult
->NumArguments() == 1)
47 CEcon
*pThis
= static_cast<CEcon
*>(pUserData
);
48 pThis
->Console()->SetPrintOutputLevel(pThis
->m_PrintCBIndex
, pResult
->GetInteger(0));
52 void CEcon::Init(IConsole
*pConsole
)
54 m_pConsole
= pConsole
;
56 for(int i
= 0; i
< NET_MAX_CONSOLE_CLIENTS
; i
++)
57 m_aClients
[i
].m_State
= CClient::STATE_EMPTY
;
61 if(g_Config
.m_EcPort
== 0 || g_Config
.m_EcPassword
[0] == 0)
65 if(g_Config
.m_EcBindaddr
[0] && net_host_lookup(g_Config
.m_EcBindaddr
, &BindAddr
, NETTYPE_ALL
) == 0)
66 BindAddr
.port
= g_Config
.m_EcPort
;
69 mem_zero(&BindAddr
, sizeof(BindAddr
));
70 BindAddr
.type
= NETTYPE_ALL
;
71 BindAddr
.port
= g_Config
.m_EcPort
;
74 if(m_NetConsole
.Open(BindAddr
, 0))
76 m_NetConsole
.SetCallbacks(NewClientCallback
, DelClientCallback
, this);
79 str_format(aBuf
, sizeof(aBuf
), "bound to %s:%d", g_Config
.m_EcBindaddr
, g_Config
.m_EcPort
);
80 Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD
,"econ", aBuf
);
82 Console()->Chain("ec_output_level", ConchainEconOutputLevelUpdate
, this);
83 m_PrintCBIndex
= Console()->RegisterPrintCallback(g_Config
.m_EcOutputLevel
, SendLineCB
, this);
86 Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD
,"econ", "couldn't open socket. port might already be in use");
94 m_NetConsole
.Update();
96 char aBuf
[NET_MAX_PACKETSIZE
];
99 while(m_NetConsole
.Recv(aBuf
, (int)(sizeof(aBuf
))-1, &ClientID
))
101 dbg_assert(m_aClients
[ClientID
].m_State
!= CClient::STATE_EMPTY
, "got message from empty slot");
102 if(m_aClients
[ClientID
].m_State
== CClient::STATE_CONNECTED
)
104 if(str_comp(aBuf
, g_Config
.m_EcPassword
) == 0)
106 m_aClients
[ClientID
].m_State
= CClient::STATE_AUTHED
;
107 m_NetConsole
.Send(ClientID
, "Authentication successful. External console access granted.");
109 str_format(aBuf
, sizeof(aBuf
), "cid=%d authed", ClientID
);
110 Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD
, "econ", aBuf
);
113 m_NetConsole
.Send(ClientID
, "Wrong password");
115 else if(m_aClients
[ClientID
].m_State
== CClient::STATE_AUTHED
)
117 char aFormatted
[256];
118 str_format(aFormatted
, sizeof(aBuf
), "cid=%d cmd='%s'", ClientID
, aBuf
);
119 Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO
, "server", aFormatted
);
120 Console()->ExecuteLine(aBuf
);
124 for(int i
= 0; i
< NET_MAX_CONSOLE_CLIENTS
; ++i
)
126 if(m_aClients
[i
].m_State
== CClient::STATE_CONNECTED
&&
127 time_get() > m_aClients
[i
].m_TimeConnected
+ g_Config
.m_EcAuthTimeout
* time_freq())
128 m_NetConsole
.Drop(i
, "authentication timeout");
132 void CEcon::Send(int ClientID
, const char *pLine
)
139 for(int i
= 0; i
< NET_MAX_CONSOLE_CLIENTS
; i
++)
141 if(m_aClients
[i
].m_State
== CClient::STATE_AUTHED
)
142 m_NetConsole
.Send(i
, pLine
);
145 else if(ClientID
>= 0 && ClientID
< NET_MAX_CONSOLE_CLIENTS
&& m_aClients
[ClientID
].m_State
== CClient::STATE_AUTHED
)
146 m_NetConsole
.Send(ClientID
, pLine
);
149 void CEcon::Shutdown()
154 m_NetConsole
.Close();