add websocket
This commit is contained in:
parent
a6ef7126be
commit
10b8c48493
@ -563,12 +563,7 @@ if(UNIX)
|
|||||||
endif()
|
endif()
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
find_package(Wavpack)
|
find_package(Wavpack)
|
||||||
if(WEBSOCKETS)
|
|
||||||
find_package(Websockets)
|
find_package(Websockets)
|
||||||
else()
|
|
||||||
set(WEBSOCKETS_LIBRARIES)
|
|
||||||
set(WEBSOCKETS_INCLUDE_DIRS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(EXCEPTION_HANDLING)
|
if(EXCEPTION_HANDLING)
|
||||||
find_package(ExceptionHandling)
|
find_package(ExceptionHandling)
|
||||||
@ -647,10 +642,7 @@ show_dependency_status("Zlib" ZLIB)
|
|||||||
if(DISCORD)
|
if(DISCORD)
|
||||||
show_dependency_status("DiscordSdk" DiscordSdk)
|
show_dependency_status("DiscordSdk" DiscordSdk)
|
||||||
endif()
|
endif()
|
||||||
if(WEBSOCKETS)
|
|
||||||
show_dependency_status("Websockets" WEBSOCKETS)
|
show_dependency_status("Websockets" WEBSOCKETS)
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CLIENT AND VULKAN)
|
if(CLIENT AND VULKAN)
|
||||||
show_dependency_status("Vulkan" VULKAN)
|
show_dependency_status("Vulkan" VULKAN)
|
||||||
endif()
|
endif()
|
||||||
@ -2467,6 +2459,7 @@ if(SERVER)
|
|||||||
name_ban.h
|
name_ban.h
|
||||||
register.cpp
|
register.cpp
|
||||||
register.h
|
register.h
|
||||||
|
ddncq.cpp
|
||||||
server.cpp
|
server.cpp
|
||||||
server.h
|
server.h
|
||||||
server_logger.cpp
|
server_logger.cpp
|
||||||
@ -3307,10 +3300,6 @@ foreach(target ${TARGETS_OWN})
|
|||||||
target_compile_definitions(${target} PRIVATE CONF_OPENSSL)
|
target_compile_definitions(${target} PRIVATE CONF_OPENSSL)
|
||||||
target_include_directories(${target} SYSTEM PRIVATE ${CRYPTO_INCLUDE_DIRS})
|
target_include_directories(${target} SYSTEM PRIVATE ${CRYPTO_INCLUDE_DIRS})
|
||||||
endif()
|
endif()
|
||||||
if(WEBSOCKETS)
|
|
||||||
target_compile_definitions(${target} PRIVATE CONF_WEBSOCKETS)
|
|
||||||
target_include_directories(${target} SYSTEM PRIVATE ${WEBSOCKETS_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
if(UPNP)
|
if(UPNP)
|
||||||
target_compile_definitions(${target} PRIVATE CONF_UPNP)
|
target_compile_definitions(${target} PRIVATE CONF_UPNP)
|
||||||
target_include_directories(${target} SYSTEM PRIVATE ${MINIUPNPC_INCLUDE_DIRS})
|
target_include_directories(${target} SYSTEM PRIVATE ${MINIUPNPC_INCLUDE_DIRS})
|
||||||
|
85
src/engine/server/ddncq.cpp
Normal file
85
src/engine/server/ddncq.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "ddncq.h"
|
||||||
|
|
||||||
|
std::vector<struct lws*> websockets;
|
||||||
|
DDNetCQ* DDNetCQ::instance=nullptr;
|
||||||
|
DDNetCQ* const ddncq=DDNetCQ::GetInstance();
|
||||||
|
#define MAX_PLAYLOAD_LEN 10*1024
|
||||||
|
int WebSocketListener( struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len ) {
|
||||||
|
switch (reason){
|
||||||
|
case LWS_CALLBACK_ESTABLISHED:
|
||||||
|
dbg_msg("ws","client connected!");
|
||||||
|
websockets.emplace_back(wsi);
|
||||||
|
break;
|
||||||
|
case LWS_CALLBACK_RECEIVE:
|
||||||
|
{
|
||||||
|
unsigned char* msg=new uint8_t[1024];
|
||||||
|
memcpy(msg,in,len);
|
||||||
|
ddncq->gamectx->SendChat(-1,CGameContext::CHAT_ALL,(const char*)msg);
|
||||||
|
delete[] msg;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LWS_CALLBACK_CLOSED:
|
||||||
|
websockets.erase(std::remove(websockets.begin(),websockets.end(),wsi));
|
||||||
|
dbg_msg("ws","client closed!");
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lws_protocols protocols[]={
|
||||||
|
{
|
||||||
|
"ws",
|
||||||
|
WebSocketListener,
|
||||||
|
MAX_PLAYLOAD_LEN/2,
|
||||||
|
MAX_PLAYLOAD_LEN
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0,0,0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
void* DDNetCQ::InitWebSocket(void* args){
|
||||||
|
struct lws_context_creation_info info;
|
||||||
|
memset(&info,0,sizeof(info));
|
||||||
|
info.port = 1111;
|
||||||
|
info.protocols = protocols;
|
||||||
|
info.gid = -1;
|
||||||
|
info.uid = -1;
|
||||||
|
struct lws_context *context = lws_create_context( &info );
|
||||||
|
while ( 1 ) {
|
||||||
|
lws_service( context, 1000 );
|
||||||
|
}
|
||||||
|
lws_context_destroy( context );
|
||||||
|
}
|
||||||
|
void DDNetCQ::OnJoinMsg(int clientID,const char* name){
|
||||||
|
for(struct lws* wsi:websockets){
|
||||||
|
if(!wsi){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unsigned char msgPack[1024]="";
|
||||||
|
sprintf((char*)msgPack,"{\"type\":\"join\",\"data\":{\"client_id\":%d,\"name\":\"%s\"}}",clientID,name);
|
||||||
|
lws_write(wsi,msgPack,strlen((char*)msgPack),LWS_WRITE_TEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDNetCQ::OnDisconnectMsg(int clientID,const char* name,const char* reason){
|
||||||
|
for(struct lws* wsi:websockets){
|
||||||
|
if(!wsi){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unsigned char msgPack[1024]="";
|
||||||
|
sprintf((char*)msgPack,"{\"type\":\"leave\",\"data\":{\"client_id\":%d,\"name\":\"%s\",\"reason\":\"%s\"}}",clientID,name,reason);
|
||||||
|
lws_write(wsi,msgPack,strlen((char*)msgPack),LWS_WRITE_TEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DDNetCQ::OnChatMsg(int clientID,const char* name,const char* msg){
|
||||||
|
for(struct lws* wsi:websockets){
|
||||||
|
if(!wsi){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unsigned char msgPack[1024]="";
|
||||||
|
sprintf((char*)msgPack,"{\"type\":\"chat\",\"data\":{\"client_id\":%d,\"name\":\"%s\",\"message\":\"%s\"}}",clientID,name,msg);
|
||||||
|
lws_write(wsi,msgPack,strlen((char*)msgPack),LWS_WRITE_TEXT);
|
||||||
|
}
|
||||||
|
}
|
27
src/engine/server/ddncq.h
Normal file
27
src/engine/server/ddncq.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <base/system.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <engine/server.h>
|
||||||
|
#include <game/server/gamecontext.h>
|
||||||
|
#include <game/server/gamecontroller.h>
|
||||||
|
#include <engine/shared/json.h>
|
||||||
|
#include <libwebsockets.h>
|
||||||
|
class DDNetCQ{
|
||||||
|
private:
|
||||||
|
static DDNetCQ* instance;
|
||||||
|
DDNetCQ(){};
|
||||||
|
~DDNetCQ(){};
|
||||||
|
public:
|
||||||
|
static DDNetCQ* GetInstance(){
|
||||||
|
if(!instance){
|
||||||
|
instance=new DDNetCQ();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
////////////////
|
||||||
|
CGameContext* gamectx=nullptr;
|
||||||
|
/////////////functions///////////////
|
||||||
|
static void* InitWebSocket(void* args);
|
||||||
|
static void OnJoinMsg(int clientID,const char* name);
|
||||||
|
static void OnDisconnectMsg(int clientID,const char* name,const char* reason);
|
||||||
|
static void OnChatMsg(int clientID,const char* name,const char* msg);
|
||||||
|
};
|
@ -20,7 +20,8 @@
|
|||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
|
|
||||||
#include <game/version.h>
|
#include <game/version.h>
|
||||||
|
#include "ddncq.h"
|
||||||
|
#include <pthread.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(CONF_FAMILY_WINDOWS)
|
#if defined(CONF_FAMILY_WINDOWS)
|
||||||
@ -29,7 +30,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
|
||||||
volatile sig_atomic_t InterruptSignaled = 0;
|
volatile sig_atomic_t InterruptSignaled = 0;
|
||||||
|
|
||||||
bool IsInterrupted()
|
bool IsInterrupted()
|
||||||
@ -186,12 +186,14 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pEngine->SetAdditionalLogger(std::make_unique<CServerLogger>(pServer));
|
pEngine->SetAdditionalLogger(std::make_unique<CServerLogger>(pServer));
|
||||||
|
dbg_msg("websocket","正在初始化WebScoket...");
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_create(&thread,nullptr,DDNetCQ::InitWebSocket,nullptr);
|
||||||
|
MysqlUninit();
|
||||||
// run the server
|
// run the server
|
||||||
dbg_msg("server", "正在启动服务器...");
|
dbg_msg("server", "正在启动服务器...");
|
||||||
int Ret = pServer->Run();
|
int Ret = pServer->Run();
|
||||||
|
|
||||||
MysqlUninit();
|
|
||||||
secure_random_uninit();
|
secure_random_uninit();
|
||||||
|
|
||||||
// free
|
// free
|
||||||
|
@ -675,7 +675,7 @@ bool CRegister::OnPacket(const CNetChunk *pPacket)
|
|||||||
|
|
||||||
void CRegister::OnNewInfo(const char *pInfo)
|
void CRegister::OnNewInfo(const char *pInfo)
|
||||||
{
|
{
|
||||||
log_trace("register", "info: %s", pInfo);
|
log_trace("register", "信息: %s", pInfo);
|
||||||
if(m_GotServerInfo && str_comp(m_aServerInfo, pInfo) == 0)
|
if(m_GotServerInfo && str_comp(m_aServerInfo, pInfo) == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -2503,7 +2503,7 @@ int CServer::LoadMap(const char *pMapName)
|
|||||||
{
|
{
|
||||||
m_pRegister->OnConfigChange();
|
m_pRegister->OnConfigChange();
|
||||||
}
|
}
|
||||||
str_format(aBufMsg, sizeof(aBufMsg), "couldn't load map %s", aBuf);
|
str_format(aBufMsg, sizeof(aBufMsg), "无法加载地图 %s", aBuf);
|
||||||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "sixup", aBufMsg);
|
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "sixup", aBufMsg);
|
||||||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "sixup", "disabling 0.7 compatibility");
|
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "sixup", "disabling 0.7 compatibility");
|
||||||
}
|
}
|
||||||
|
6
src/game/server/ddracechat.cpp
Executable file → Normal file
6
src/game/server/ddracechat.cpp
Executable file → Normal file
@ -662,13 +662,13 @@ void CGameContext::ConPractice(IConsole::IResult *pResult, void *pUserData)
|
|||||||
int NumRequiredVotes = TeamSize / 2 + 1;
|
int NumRequiredVotes = TeamSize / 2 + 1;
|
||||||
|
|
||||||
char aBuf[512];
|
char aBuf[512];
|
||||||
str_format(aBuf, sizeof(aBuf), "'%s' voted to %s /practice mode for your team, which means you can use /r, but you can't earn a rank. Type /practice to vote (%d/%d required votes)", pSelf->Server()->ClientName(pResult->m_ClientID), VotedForPractice ? "enable" : "disable", NumCurrentVotes, NumRequiredVotes);
|
str_format(aBuf, sizeof(aBuf), "%s 想通过投票为队伍%s训练模式,这意味着你可以直接使用 /r 命令,但你无法获得排名 输入 /practice 来投票 (%d/%d 已投票)", pSelf->Server()->ClientName(pResult->m_ClientID), VotedForPractice ? "启用" : "禁用", NumCurrentVotes, NumRequiredVotes);
|
||||||
pSelf->SendChatTeam(Team, aBuf);
|
pSelf->SendChatTeam(Team, aBuf);
|
||||||
|
|
||||||
if(NumCurrentVotes >= NumRequiredVotes)
|
if(NumCurrentVotes >= NumRequiredVotes)
|
||||||
{
|
{
|
||||||
Teams.SetPractice(Team, true);
|
Teams.SetPractice(Team, true);
|
||||||
pSelf->SendChatTeam(Team, "为你的队伍启用练习模式");
|
pSelf->SendChatTeam(Team, "已为你的队伍启用练习模式");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1067,7 +1067,7 @@ void CGameContext::ConJoinTeam(IConsole::IResult *pResult, void *pUserData)
|
|||||||
pPlayer->m_Last_Team = pSelf->Server()->Tick();
|
pPlayer->m_Last_Team = pSelf->Server()->Tick();
|
||||||
|
|
||||||
if(pController->m_Teams.IsPractice(Team))
|
if(pController->m_Teams.IsPractice(Team))
|
||||||
pSelf->SendChatTarget(pPlayer->GetCID(), "Practice mode enabled for your team, happy practicing!");
|
pSelf->SendChatTarget(pPlayer->GetCID(), "你的队伍正处于训练模式,祝你好运!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
src/game/server/ddracecommands.cpp
Executable file → Normal file
6
src/game/server/ddracecommands.cpp
Executable file → Normal file
@ -496,9 +496,9 @@ void CGameContext::Mute(const NETADDR *pAddr, int Secs, const char *pDisplayName
|
|||||||
|
|
||||||
char aBuf[128];
|
char aBuf[128];
|
||||||
if(pReason[0])
|
if(pReason[0])
|
||||||
str_format(aBuf, sizeof aBuf, "'%s' has been muted for %d seconds (%s)", pDisplayName, Secs, pReason);
|
str_format(aBuf, sizeof aBuf, "'%s 被禁言 %d 秒 (%s)", pDisplayName, Secs, pReason);
|
||||||
else
|
else
|
||||||
str_format(aBuf, sizeof aBuf, "'%s' has been muted for %d seconds", pDisplayName, Secs);
|
str_format(aBuf, sizeof aBuf, "'%s' 被禁言 %d 秒", pDisplayName, Secs);
|
||||||
SendChat(-1, CHAT_ALL, aBuf);
|
SendChat(-1, CHAT_ALL, aBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +539,7 @@ void CGameContext::ConVoteUnmute(IConsole::IResult *pResult, void *pUserData)
|
|||||||
if(Found)
|
if(Found)
|
||||||
{
|
{
|
||||||
char aBuf[128];
|
char aBuf[128];
|
||||||
str_format(aBuf, sizeof aBuf, "'%s' unbanned '%s' from voting.",
|
str_format(aBuf, sizeof aBuf, "'%s 投票解除%s的封禁",
|
||||||
pSelf->Server()->ClientName(pResult->m_ClientID), pSelf->Server()->ClientName(Victim));
|
pSelf->Server()->ClientName(pResult->m_ClientID), pSelf->Server()->ClientName(Victim));
|
||||||
pSelf->SendChat(-1, 0, aBuf);
|
pSelf->SendChat(-1, 0, aBuf);
|
||||||
}
|
}
|
||||||
|
4
src/game/server/entities/character.cpp
Executable file → Normal file
4
src/game/server/entities/character.cpp
Executable file → Normal file
@ -1515,7 +1515,7 @@ void CCharacter::HandleTiles(int Index)
|
|||||||
// unlimited air jumps
|
// unlimited air jumps
|
||||||
if(((m_TileIndex == TILE_UNLIMITED_JUMPS_ENABLE) || (m_TileFIndex == TILE_UNLIMITED_JUMPS_ENABLE)) && !m_Core.m_EndlessJump)
|
if(((m_TileIndex == TILE_UNLIMITED_JUMPS_ENABLE) || (m_TileFIndex == TILE_UNLIMITED_JUMPS_ENABLE)) && !m_Core.m_EndlessJump)
|
||||||
{
|
{
|
||||||
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "你用有了无限空中跳跃");
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "你拥有了无限跳跃");
|
||||||
m_Core.m_EndlessJump = true;
|
m_Core.m_EndlessJump = true;
|
||||||
if(m_Core.m_Jumps == 0)
|
if(m_Core.m_Jumps == 0)
|
||||||
{
|
{
|
||||||
@ -1525,7 +1525,7 @@ void CCharacter::HandleTiles(int Index)
|
|||||||
}
|
}
|
||||||
else if(((m_TileIndex == TILE_UNLIMITED_JUMPS_DISABLE) || (m_TileFIndex == TILE_UNLIMITED_JUMPS_DISABLE)) && m_Core.m_EndlessJump)
|
else if(((m_TileIndex == TILE_UNLIMITED_JUMPS_DISABLE) || (m_TileFIndex == TILE_UNLIMITED_JUMPS_DISABLE)) && m_Core.m_EndlessJump)
|
||||||
{
|
{
|
||||||
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "你没有无限空中跳跃");
|
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "你失去了无限跳跃");
|
||||||
m_Core.m_EndlessJump = false;
|
m_Core.m_EndlessJump = false;
|
||||||
if(m_Core.m_Jumps == 0)
|
if(m_Core.m_Jumps == 0)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "score.h"
|
#include "score.h"
|
||||||
|
|
||||||
|
#include <engine/server/ddncq.h>
|
||||||
// Not thread-safe!
|
// Not thread-safe!
|
||||||
class CClientChatLogger : public ILogger
|
class CClientChatLogger : public ILogger
|
||||||
{
|
{
|
||||||
@ -513,8 +514,9 @@ void CGameContext::SendChat(int ChatterClientID, int Team, const char *pText, in
|
|||||||
|
|
||||||
char aBuf[256], aText[256];
|
char aBuf[256], aText[256];
|
||||||
str_copy(aText, pText, sizeof(aText));
|
str_copy(aText, pText, sizeof(aText));
|
||||||
if(ChatterClientID >= 0 && ChatterClientID < MAX_CLIENTS)
|
if(ChatterClientID >= 0 && ChatterClientID < MAX_CLIENTS){
|
||||||
str_format(aBuf, sizeof(aBuf), "[%d:%d:%s]: %s", ChatterClientID, Team, Server()->ClientName(ChatterClientID), aText);
|
str_format(aBuf, sizeof(aBuf), "[%d:%d:%s]: %s", ChatterClientID, Team, Server()->ClientName(ChatterClientID), aText);
|
||||||
|
}
|
||||||
else if(ChatterClientID == -2)
|
else if(ChatterClientID == -2)
|
||||||
{
|
{
|
||||||
str_format(aBuf, sizeof(aBuf), "### %s", aText);
|
str_format(aBuf, sizeof(aBuf), "### %s", aText);
|
||||||
@ -549,6 +551,8 @@ void CGameContext::SendChat(int ChatterClientID, int Team, const char *pText, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
str_format(aBuf, sizeof aBuf, "Chat: %s", aText);
|
str_format(aBuf, sizeof aBuf, "Chat: %s", aText);
|
||||||
|
if(ChatterClientID!=-1)
|
||||||
|
DDNetCQ::OnChatMsg(ChatterClientID,Server()->ClientName(ChatterClientID),aText);
|
||||||
LogEvent(aBuf, ChatterClientID);
|
LogEvent(aBuf, ChatterClientID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
#include <game/server/player.h>
|
#include <game/server/player.h>
|
||||||
#include <game/server/score.h>
|
#include <game/server/score.h>
|
||||||
#include <game/version.h>
|
#include <game/version.h>
|
||||||
|
#include <engine/server/ddncq.h>
|
||||||
CGameControllerDDRace::CGameControllerDDRace(class CGameContext *pGameServer) :
|
CGameControllerDDRace::CGameControllerDDRace(class CGameContext *pGameServer) :
|
||||||
IGameController(pGameServer), m_Teams(pGameServer), m_pLoadBestTimeResult(nullptr)
|
IGameController(pGameServer), m_Teams(pGameServer), m_pLoadBestTimeResult(nullptr)
|
||||||
{
|
{
|
||||||
m_pGameType = g_Config.m_SvModeName;
|
m_pGameType = g_Config.m_SvModeName;
|
||||||
|
DDNetCQ::GetInstance()->gamectx=pGameServer;
|
||||||
InitTeleporter();
|
InitTeleporter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +136,7 @@ void CGameControllerDDRace::OnPlayerConnect(CPlayer *pPlayer)
|
|||||||
char aBuf[512];
|
char aBuf[512];
|
||||||
str_format(aBuf, sizeof(aBuf), "'%s' 已加入游戏", Server()->ClientName(ClientID));
|
str_format(aBuf, sizeof(aBuf), "'%s' 已加入游戏", Server()->ClientName(ClientID));
|
||||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf, -1, CGameContext::CHAT_SIX);
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf, -1, CGameContext::CHAT_SIX);
|
||||||
|
DDNetCQ::OnJoinMsg(ClientID,Server()->ClientName(ClientID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +146,7 @@ void CGameControllerDDRace::OnPlayerDisconnect(CPlayer *pPlayer, const char *pRe
|
|||||||
bool WasModerator = pPlayer->m_Moderating && Server()->ClientIngame(ClientID);
|
bool WasModerator = pPlayer->m_Moderating && Server()->ClientIngame(ClientID);
|
||||||
|
|
||||||
IGameController::OnPlayerDisconnect(pPlayer, pReason);
|
IGameController::OnPlayerDisconnect(pPlayer, pReason);
|
||||||
|
DDNetCQ::OnDisconnectMsg(ClientID,Server()->ClientName(ClientID),pReason);
|
||||||
|
|
||||||
if(!GameServer()->PlayerModerating() && WasModerator)
|
if(!GameServer()->PlayerModerating() && WasModerator)
|
||||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Server kick/spec votes are no longer actively moderated.");
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Server kick/spec votes are no longer actively moderated.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user