mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-19 17:14:18 +00:00
Compare commits
26 commits
d0b2c48266
...
21584980bc
Author | SHA1 | Date | |
---|---|---|---|
21584980bc | |||
a2e0ab2dbe | |||
255694c061 | |||
b475c67039 | |||
a266cd2f70 | |||
2c77e79061 | |||
ChillerDragon | 46c5344d71 | ||
96ad30eb21 | |||
b03245f7dd | |||
ChillerDragon | 7192bbf397 | ||
ChillerDragon | 984845b2a9 | ||
60624d5599 | |||
9d7b476c33 | |||
f27086df60 | |||
ec4f377194 | |||
3eefa68534 | |||
a202751ada | |||
81f4c736e4 | |||
7bdf2e644f | |||
0d84dcbaef | |||
7de808ae99 | |||
9c6e8c98e6 | |||
e3723d3843 | |||
c90dbe5ba0 | |||
9e279d1049 | |||
4b6a10624c |
|
@ -996,6 +996,7 @@ endif()
|
|||
########################################################################
|
||||
|
||||
set(EXPECTED_DATA
|
||||
announcement.txt
|
||||
arrow.png
|
||||
assets/entities/comfort/ddnet.png
|
||||
assets/entities/license.txt
|
||||
|
|
0
data/announcement.txt
Normal file
0
data/announcement.txt
Normal file
|
@ -80,10 +80,10 @@ sv_rescue_delay 5
|
|||
# Message on chat displayed when joining
|
||||
sv_welcome "Welcome to my server!"
|
||||
|
||||
# File which will have the announcements (each one in new line)
|
||||
# File which contains the announcements (One on each line)
|
||||
sv_announcement_filename "announcement.txt"
|
||||
|
||||
# Number of minutes before next announcement will be displayed (from the announcement file)
|
||||
# Number of minutes before the next announcement will be displayed (from the announcement file)
|
||||
sv_announcement_interval 120
|
||||
|
||||
# Whether announcements will be displayed in their order or chosen randomly
|
||||
|
|
|
@ -80,6 +80,7 @@ void CInput::Init()
|
|||
|
||||
m_pGraphics = Kernel()->RequestInterface<IEngineGraphics>();
|
||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||
m_pConfigManager = Kernel()->RequestInterface<IConfigManager>();
|
||||
|
||||
MouseModeRelative();
|
||||
|
||||
|
@ -824,6 +825,9 @@ int CInput::Update()
|
|||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
#if defined(CONF_PLATFORM_ANDROID) // Save the config when minimized on Android.
|
||||
m_pConfigManager->Save();
|
||||
#endif
|
||||
Graphics()->WindowDestroyNtf(Event.window.windowID);
|
||||
break;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <vector>
|
||||
|
||||
class IEngineGraphics;
|
||||
class IConfigManager;
|
||||
|
||||
class CInput : public IEngineInput
|
||||
{
|
||||
|
@ -59,6 +60,7 @@ public:
|
|||
private:
|
||||
IEngineGraphics *m_pGraphics;
|
||||
IConsole *m_pConsole;
|
||||
IConfigManager *m_pConfigManager;
|
||||
|
||||
IEngineGraphics *Graphics() const { return m_pGraphics; }
|
||||
IConsole *Console() const { return m_pConsole; }
|
||||
|
|
|
@ -273,7 +273,8 @@ public:
|
|||
virtual bool DnsblWhite(int ClientId) = 0;
|
||||
virtual bool DnsblPending(int ClientId) = 0;
|
||||
virtual bool DnsblBlack(int ClientId) = 0;
|
||||
virtual const char *GetAnnouncementLine(const char *pFileName) = 0;
|
||||
virtual const char *GetAnnouncementLine() = 0;
|
||||
virtual void ReadAnnouncementsFile(const char *pFileName) = 0;
|
||||
virtual bool ClientPrevIngame(int ClientId) = 0;
|
||||
virtual const char *GetNetErrorString(int ClientId) = 0;
|
||||
virtual void ResetNetErrorString(int ClientId) = 0;
|
||||
|
@ -332,9 +333,8 @@ public:
|
|||
virtual void OnClientEnter(int ClientId) = 0;
|
||||
virtual void OnClientDrop(int ClientId, const char *pReason) = 0;
|
||||
virtual void OnClientPrepareInput(int ClientId, void *pInput) = 0;
|
||||
virtual void OnClientDirectInput(int ClientId, void *pInput) = 0;
|
||||
virtual void OnClientFreshInput(int ClientId, void *pInput) = 0;
|
||||
virtual void OnClientPredictedInput(int ClientId, void *pInput) = 0;
|
||||
virtual void OnClientPredictedEarlyInput(int ClientId, void *pInput) = 0;
|
||||
|
||||
virtual bool IsClientReady(int ClientId) const = 0;
|
||||
virtual bool IsClientPlayer(int ClientId) const = 0;
|
||||
|
|
|
@ -208,8 +208,6 @@ void CServer::CClient::Reset()
|
|||
// reset input
|
||||
for(auto &Input : m_aInputs)
|
||||
Input.m_GameTick = -1;
|
||||
m_CurrentInput = 0;
|
||||
mem_zero(&m_LatestInput, sizeof(m_LatestInput));
|
||||
|
||||
m_Snapshots.PurgeAll();
|
||||
m_LastAckedSnapshot = -1;
|
||||
|
@ -537,8 +535,7 @@ int CServer::Init()
|
|||
|
||||
m_CurrentGameTick = MIN_TICK;
|
||||
|
||||
m_AnnouncementLastLine = 0;
|
||||
m_aAnnouncementFile[0] = '\0';
|
||||
m_AnnouncementLastLine = -1;
|
||||
mem_zero(m_aPrevStates, sizeof(m_aPrevStates));
|
||||
|
||||
return 0;
|
||||
|
@ -1634,12 +1631,22 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
const int LastAckedSnapshot = Unpacker.GetInt();
|
||||
int IntendedTick = Unpacker.GetInt();
|
||||
int Size = Unpacker.GetInt();
|
||||
|
||||
int BufferPosition = IntendedTick % 200;
|
||||
// The client is not allowed to change inputs for a tick they have already sent to the server
|
||||
if(m_aClients[ClientId].m_aInputs[BufferPosition].m_GameTick == IntendedTick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(Unpacker.Error() || Size / 4 > MAX_INPUT_SIZE || IntendedTick < MIN_TICK || IntendedTick >= MAX_TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// The LastAckedSnapshot should only increase
|
||||
if(LastAckedSnapshot > m_aClients[ClientId].m_LastAckedSnapshot || LastAckedSnapshot == -1)
|
||||
m_aClients[ClientId].m_LastAckedSnapshot = LastAckedSnapshot;
|
||||
|
||||
if(m_aClients[ClientId].m_LastAckedSnapshot > 0)
|
||||
m_aClients[ClientId].m_SnapRate = CClient::SNAPRATE_FULL;
|
||||
|
||||
|
@ -1661,11 +1668,18 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
|
||||
m_aClients[ClientId].m_LastInputTick = IntendedTick;
|
||||
|
||||
CClient::CInput *pInput = &m_aClients[ClientId].m_aInputs[m_aClients[ClientId].m_CurrentInput];
|
||||
|
||||
// TODO: This should probably not be here, the most recent input can be found by looping over the ring buffer
|
||||
// so we should not change the inputs original intended tick since we might need that information
|
||||
if(IntendedTick <= Tick())
|
||||
IntendedTick = Tick() + 1;
|
||||
|
||||
// Check once again that we are not overriding an input the client has already sent
|
||||
// This is a workaround while the above code is still able to change IntendedTick
|
||||
BufferPosition = IntendedTick % 200;
|
||||
if(m_aClients[ClientId].m_aInputs[BufferPosition].m_GameTick == IntendedTick)
|
||||
return;
|
||||
|
||||
CClient::CInput *pInput = &m_aClients[ClientId].m_aInputs[BufferPosition];
|
||||
pInput->m_GameTick = IntendedTick;
|
||||
|
||||
for(int i = 0; i < Size / 4; i++)
|
||||
|
@ -1678,14 +1692,13 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
}
|
||||
|
||||
GameServer()->OnClientPrepareInput(ClientId, pInput->m_aData);
|
||||
mem_copy(m_aClients[ClientId].m_LatestInput.m_aData, pInput->m_aData, MAX_INPUT_SIZE * sizeof(int));
|
||||
|
||||
m_aClients[ClientId].m_CurrentInput++;
|
||||
m_aClients[ClientId].m_CurrentInput %= 200;
|
||||
CClient::CInput LatestInput;
|
||||
mem_copy(LatestInput.m_aData, pInput->m_aData, MAX_INPUT_SIZE * sizeof(int));
|
||||
|
||||
// call the mod with the fresh input data
|
||||
if(m_aClients[ClientId].m_State == CClient::STATE_INGAME)
|
||||
GameServer()->OnClientDirectInput(ClientId, m_aClients[ClientId].m_LatestInput.m_aData);
|
||||
GameServer()->OnClientFreshInput(ClientId, LatestInput.m_aData);
|
||||
}
|
||||
else if(Msg == NETMSG_RCON_CMD)
|
||||
{
|
||||
|
@ -2667,8 +2680,6 @@ void CServer::UpdateDebugDummies(bool ForceDisconnect)
|
|||
Input.m_Direction = (ClientId & 1) ? -1 : 1;
|
||||
m_aClients[ClientId].m_aInputs[0].m_GameTick = Tick() + 1;
|
||||
mem_copy(m_aClients[ClientId].m_aInputs[0].m_aData, &Input, minimum(sizeof(Input), sizeof(m_aClients[ClientId].m_aInputs[0].m_aData)));
|
||||
m_aClients[ClientId].m_LatestInput = m_aClients[ClientId].m_aInputs[0];
|
||||
m_aClients[ClientId].m_CurrentInput = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2783,6 +2794,8 @@ int CServer::Run()
|
|||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||
}
|
||||
|
||||
ReadAnnouncementsFile(g_Config.m_SvAnnouncementFileName);
|
||||
|
||||
// process pending commands
|
||||
m_pConsole->StoreCommands(false);
|
||||
m_pRegister->OnConfigChange();
|
||||
|
@ -2887,23 +2900,6 @@ int CServer::Run()
|
|||
UpdateDebugDummies(false);
|
||||
#endif
|
||||
|
||||
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||
{
|
||||
if(m_aClients[c].m_State != CClient::STATE_INGAME)
|
||||
continue;
|
||||
bool ClientHadInput = false;
|
||||
for(auto &Input : m_aClients[c].m_aInputs)
|
||||
{
|
||||
if(Input.m_GameTick == Tick() + 1)
|
||||
{
|
||||
GameServer()->OnClientPredictedEarlyInput(c, Input.m_aData);
|
||||
ClientHadInput = true;
|
||||
}
|
||||
}
|
||||
if(!ClientHadInput)
|
||||
GameServer()->OnClientPredictedEarlyInput(c, nullptr);
|
||||
}
|
||||
|
||||
m_CurrentGameTick++;
|
||||
NewTicks++;
|
||||
|
||||
|
@ -2925,7 +2921,6 @@ int CServer::Run()
|
|||
if(!ClientHadInput)
|
||||
GameServer()->OnClientPredictedInput(c, nullptr);
|
||||
}
|
||||
|
||||
GameServer()->OnTick();
|
||||
if(ErrorShutdown())
|
||||
{
|
||||
|
@ -3809,6 +3804,17 @@ void CServer::ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserD
|
|||
}
|
||||
}
|
||||
|
||||
void CServer::ConchainAnnouncementFileName(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
CServer *pSelf = (CServer *)pUserData;
|
||||
bool Changed = pResult->NumArguments() && str_comp(pResult->GetString(0), g_Config.m_SvAnnouncementFileName);
|
||||
pfnCallback(pResult, pCallbackUserData);
|
||||
if(Changed)
|
||||
{
|
||||
pSelf->ReadAnnouncementsFile(g_Config.m_SvAnnouncementFileName);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
void CServer::ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
|
@ -3887,6 +3893,8 @@ void CServer::RegisterCommands()
|
|||
Console()->Chain("loglevel", ConchainLoglevel, this);
|
||||
Console()->Chain("stdout_output_level", ConchainStdoutOutputLevel, this);
|
||||
|
||||
Console()->Chain("sv_announcement_filename", ConchainAnnouncementFileName, this);
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
Console()->Chain("sv_conn_logging_server", ConchainConnLoggingServerChange, this);
|
||||
#endif
|
||||
|
@ -3930,17 +3938,18 @@ void CServer::GetClientAddr(int ClientId, NETADDR *pAddr) const
|
|||
}
|
||||
}
|
||||
|
||||
const char *CServer::GetAnnouncementLine(const char *pFileName)
|
||||
void CServer::ReadAnnouncementsFile(const char *pFileName)
|
||||
{
|
||||
if(str_comp(pFileName, m_aAnnouncementFile) != 0)
|
||||
{
|
||||
str_copy(m_aAnnouncementFile, pFileName);
|
||||
m_vAnnouncements.clear();
|
||||
|
||||
if(pFileName[0] == '\0')
|
||||
return;
|
||||
|
||||
CLineReader LineReader;
|
||||
if(!LineReader.OpenFile(m_pStorage->OpenFile(pFileName, IOFLAG_READ, IStorage::TYPE_ALL)))
|
||||
{
|
||||
return 0;
|
||||
dbg_msg("announcements", "failed to open '%s'", pFileName);
|
||||
return;
|
||||
}
|
||||
while(const char *pLine = LineReader.Get())
|
||||
{
|
||||
|
@ -3949,8 +3958,10 @@ const char *CServer::GetAnnouncementLine(const char *pFileName)
|
|||
m_vAnnouncements.emplace_back(pLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *CServer::GetAnnouncementLine()
|
||||
{
|
||||
if(m_vAnnouncements.empty())
|
||||
{
|
||||
return 0;
|
||||
|
@ -3959,7 +3970,7 @@ const char *CServer::GetAnnouncementLine(const char *pFileName)
|
|||
{
|
||||
m_AnnouncementLastLine = 0;
|
||||
}
|
||||
else if(!Config()->m_SvAnnouncementRandom)
|
||||
else if(!g_Config.m_SvAnnouncementRandom)
|
||||
{
|
||||
if(++m_AnnouncementLastLine >= m_vAnnouncements.size())
|
||||
m_AnnouncementLastLine %= m_vAnnouncements.size();
|
||||
|
|
|
@ -147,9 +147,7 @@ public:
|
|||
int m_LastInputTick;
|
||||
CSnapshotStorage m_Snapshots;
|
||||
|
||||
CInput m_LatestInput;
|
||||
CInput m_aInputs[200]; // TODO: handle input better
|
||||
int m_CurrentInput;
|
||||
CInput m_aInputs[200];
|
||||
|
||||
char m_aName[MAX_NAME_LENGTH];
|
||||
char m_aClan[MAX_CLAN_LENGTH];
|
||||
|
@ -259,7 +257,6 @@ public:
|
|||
|
||||
size_t m_AnnouncementLastLine;
|
||||
std::vector<std::string> m_vAnnouncements;
|
||||
char m_aAnnouncementFile[IO_MAX_PATH_LENGTH];
|
||||
|
||||
std::shared_ptr<ILogger> m_pFileLogger = nullptr;
|
||||
std::shared_ptr<ILogger> m_pStdoutLogger = nullptr;
|
||||
|
@ -427,6 +424,7 @@ public:
|
|||
static void ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
static void ConchainAnnouncementFileName(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
|
@ -443,7 +441,8 @@ public:
|
|||
|
||||
void GetClientAddr(int ClientId, NETADDR *pAddr) const override;
|
||||
int m_aPrevStates[MAX_CLIENTS];
|
||||
const char *GetAnnouncementLine(const char *pFileName) override;
|
||||
const char *GetAnnouncementLine() override;
|
||||
void ReadAnnouncementsFile(const char *pFileName) override;
|
||||
|
||||
int *GetIdMap(int ClientId) override;
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ MACRO_CONFIG_INT(SvWarmup, sv_warmup, 0, 0, 0, CFGFLAG_SERVER, "Number of second
|
|||
MACRO_CONFIG_STR(SvMotd, sv_motd, 900, "", CFGFLAG_SERVER, "Message of the day to display for the clients")
|
||||
MACRO_CONFIG_STR(SvGametype, sv_gametype, 32, "ddnet", CFGFLAG_SERVER, "Game type (ddnet, mod)")
|
||||
MACRO_CONFIG_INT(SvTournamentMode, sv_tournament_mode, 0, 0, 1, CFGFLAG_SERVER, "Tournament mode. When enabled, players joins the server as spectator")
|
||||
MACRO_CONFIG_INT(SvSpamprotection, sv_spamprotection, 1, 0, 1, CFGFLAG_SERVER, "Spam protection")
|
||||
MACRO_CONFIG_INT(SvSpamprotection, sv_spamprotection, 1, 0, 1, CFGFLAG_SERVER, "Spam protection for: team change, chat, skin change, emotes and votes")
|
||||
|
||||
MACRO_CONFIG_INT(SvSpectatorSlots, sv_spectator_slots, 0, 0, MAX_CLIENTS, CFGFLAG_SERVER, "Number of slots to reserve for spectators")
|
||||
MACRO_CONFIG_INT(SvInactiveKickTime, sv_inactivekick_time, 0, 0, 1000, CFGFLAG_SERVER, "How many minutes to wait before taking care of inactive players")
|
||||
|
@ -548,8 +548,8 @@ MACRO_CONFIG_INT(SvMinTeamSize, sv_min_team_size, 2, 1, MAX_CLIENTS, CFGFLAG_SER
|
|||
MACRO_CONFIG_INT(SvMaxTeamSize, sv_max_team_size, MAX_CLIENTS, 1, MAX_CLIENTS, CFGFLAG_SERVER | CFGFLAG_GAME, "Maximum team size")
|
||||
MACRO_CONFIG_INT(SvMapVote, sv_map_vote, 1, 0, 1, CFGFLAG_SERVER, "Whether to allow /map")
|
||||
|
||||
MACRO_CONFIG_STR(SvAnnouncementFileName, sv_announcement_filename, 24, "announcement.txt", CFGFLAG_SERVER, "file which will have the announcement, each one at a line")
|
||||
MACRO_CONFIG_INT(SvAnnouncementInterval, sv_announcement_interval, 300, 1, 9999, CFGFLAG_SERVER, "time(minutes) in which the announcement will be displayed from the announcement file")
|
||||
MACRO_CONFIG_STR(SvAnnouncementFileName, sv_announcement_filename, IO_MAX_PATH_LENGTH, "announcement.txt", CFGFLAG_SERVER, "File which contains the announcements, one on each line")
|
||||
MACRO_CONFIG_INT(SvAnnouncementInterval, sv_announcement_interval, 120, 1, 9999, CFGFLAG_SERVER, "The time (minutes) for how often an announcement will be displayed from the announcement file")
|
||||
MACRO_CONFIG_INT(SvAnnouncementRandom, sv_announcement_random, 1, 0, 1, CFGFLAG_SERVER, "Whether announcements are sequential or random")
|
||||
|
||||
MACRO_CONFIG_INT(SvOldLaser, sv_old_laser, 0, 0, 1, CFGFLAG_SERVER | CFGFLAG_GAME, "Whether lasers can hit you if you shot them and that they pull you towards the bounce origin (0 for all new maps) or lasers can't hit you if you shot them, and they pull others towards the shooter")
|
||||
|
|
|
@ -1565,7 +1565,7 @@ void CGameClient::OnNewSnapshot()
|
|||
pClient->m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
|
||||
}
|
||||
|
||||
pClient->UpdateRenderInfo(IsTeamPlay(), g_Config.m_ClDummy);
|
||||
pClient->UpdateRenderInfo(IsTeamPlay());
|
||||
}
|
||||
}
|
||||
else if(Item.m_Type == NETOBJTYPE_PLAYERINFO)
|
||||
|
@ -2388,7 +2388,7 @@ void CGameClient::CClientStats::Reset()
|
|||
m_FlagCaptures = 0;
|
||||
}
|
||||
|
||||
void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay, int Conn)
|
||||
void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay)
|
||||
{
|
||||
m_RenderInfo = m_SkinInfo;
|
||||
|
||||
|
@ -2403,6 +2403,7 @@ void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay, int Conn)
|
|||
m_RenderInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(aTeamColors[m_Team]));
|
||||
|
||||
// 0.7
|
||||
for(auto &Sixup : m_RenderInfo.m_aSixup)
|
||||
{
|
||||
const ColorRGBA aTeamColorsSixup[2] = {
|
||||
ColorRGBA(0.753f, 0.318f, 0.318f, 1.0f),
|
||||
|
@ -2410,18 +2411,19 @@ void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay, int Conn)
|
|||
const ColorRGBA aMarkingColorsSixup[2] = {
|
||||
ColorRGBA(0.824f, 0.345f, 0.345f, 1.0f),
|
||||
ColorRGBA(0.345f, 0.514f, 0.824f, 1.0f)};
|
||||
float MarkingAlpha = m_RenderInfo.m_aSixup[Conn].m_aColors[protocol7::SKINPART_MARKING].a;
|
||||
for(auto &Color : m_RenderInfo.m_aSixup[Conn].m_aColors)
|
||||
float MarkingAlpha = Sixup.m_aColors[protocol7::SKINPART_MARKING].a;
|
||||
for(auto &Color : Sixup.m_aColors)
|
||||
Color = aTeamColorsSixup[m_Team];
|
||||
if(MarkingAlpha > 0.1f)
|
||||
m_RenderInfo.m_aSixup[Conn].m_aColors[protocol7::SKINPART_MARKING] = aMarkingColorsSixup[m_Team];
|
||||
Sixup.m_aColors[protocol7::SKINPART_MARKING] = aMarkingColorsSixup[m_Team];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RenderInfo.m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
||||
m_RenderInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
||||
for(auto &Color : m_RenderInfo.m_aSixup[Conn].m_aColors)
|
||||
for(auto &Sixup : m_RenderInfo.m_aSixup)
|
||||
for(auto &Color : Sixup.m_aColors)
|
||||
Color = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
||||
}
|
||||
}
|
||||
|
@ -3757,8 +3759,7 @@ void CGameClient::RefreshSkins()
|
|||
Client.m_SkinInfo.m_OriginalRenderSkin.Reset();
|
||||
Client.m_SkinInfo.m_ColorableRenderSkin.Reset();
|
||||
}
|
||||
for(int Dummy = 0; Dummy < NUM_DUMMIES; Dummy++)
|
||||
Client.UpdateRenderInfo(IsTeamPlay(), Dummy);
|
||||
Client.UpdateRenderInfo(IsTeamPlay());
|
||||
}
|
||||
|
||||
for(auto &pComponent : m_vpAll)
|
||||
|
|
|
@ -438,7 +438,7 @@ public:
|
|||
bool m_SpecCharPresent;
|
||||
vec2 m_SpecChar;
|
||||
|
||||
void UpdateRenderInfo(bool IsTeamPlay, int Conn);
|
||||
void UpdateRenderInfo(bool IsTeamPlay);
|
||||
void Reset();
|
||||
|
||||
class CSixup
|
||||
|
|
|
@ -196,7 +196,7 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
{
|
||||
m_aClients[pMsg7->m_ClientId].m_Team = pMsg7->m_Team;
|
||||
m_pClient->m_TranslationContext.m_aClients[pMsg7->m_ClientId].m_Team = pMsg7->m_Team;
|
||||
m_aClients[pMsg7->m_ClientId].UpdateRenderInfo(IsTeamPlay(), Conn);
|
||||
m_aClients[pMsg7->m_ClientId].UpdateRenderInfo(IsTeamPlay());
|
||||
|
||||
// if(pMsg7->m_ClientId == m_LocalClientId)
|
||||
// {
|
||||
|
@ -620,9 +620,11 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
switch(GameMsgId)
|
||||
{
|
||||
case protocol7::GAMEMSG_CTF_DROP:
|
||||
if(Conn == g_Config.m_ClDummy)
|
||||
m_Sounds.Enqueue(CSounds::CHN_GLOBAL, SOUND_CTF_DROP);
|
||||
break;
|
||||
case protocol7::GAMEMSG_CTF_RETURN:
|
||||
if(Conn == g_Config.m_ClDummy)
|
||||
m_Sounds.Enqueue(CSounds::CHN_GLOBAL, SOUND_CTF_RETURN);
|
||||
break;
|
||||
case protocol7::GAMEMSG_TEAM_ALL:
|
||||
|
@ -650,6 +652,7 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
}
|
||||
break;
|
||||
case protocol7::GAMEMSG_CTF_GRAB:
|
||||
if(Conn == g_Config.m_ClDummy)
|
||||
m_Sounds.Enqueue(CSounds::CHN_GLOBAL, SOUND_CTF_GRAB_EN);
|
||||
break;
|
||||
case protocol7::GAMEMSG_GAME_PAUSED:
|
||||
|
@ -660,6 +663,7 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
|||
}
|
||||
break;
|
||||
case protocol7::GAMEMSG_CTF_CAPTURE:
|
||||
if(Conn == g_Config.m_ClDummy)
|
||||
m_Sounds.Enqueue(CSounds::CHN_GLOBAL, SOUND_CTF_CAPTURE);
|
||||
int ClientId = clamp(aParaI[1], 0, MAX_CLIENTS - 1);
|
||||
m_aStats[ClientId].m_FlagCaptures++;
|
||||
|
|
|
@ -893,6 +893,12 @@ void CGameContext::ConReloadCensorlist(IConsole::IResult *pResult, void *pUserDa
|
|||
pSelf->ReadCensorList();
|
||||
}
|
||||
|
||||
void CGameContext::ConReloadAnnouncement(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
pSelf->Server()->ReadAnnouncementsFile(g_Config.m_SvAnnouncementFileName);
|
||||
}
|
||||
|
||||
void CGameContext::ConDumpAntibot(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
|
|
@ -403,7 +403,7 @@ void CCharacter::HandleWeaponSwitch()
|
|||
DoWeaponSwitch();
|
||||
}
|
||||
|
||||
void CCharacter::FireWeapon()
|
||||
void CCharacter::FireWeapon(bool EarlyFire)
|
||||
{
|
||||
if(m_ReloadTimer != 0)
|
||||
{
|
||||
|
@ -530,7 +530,7 @@ void CCharacter::FireWeapon()
|
|||
{
|
||||
int Lifetime = (int)(Server()->TickSpeed() * GetTuning(m_TuneZone)->m_GunLifetime);
|
||||
|
||||
new CProjectile(
|
||||
CProjectile *Projectile = new CProjectile(
|
||||
GameWorld(),
|
||||
WEAPON_GUN, //Type
|
||||
m_pPlayer->GetCid(), //Owner
|
||||
|
@ -542,6 +542,8 @@ void CCharacter::FireWeapon()
|
|||
-1, //SoundImpact
|
||||
MouseTarget //InitDir
|
||||
);
|
||||
if(EarlyFire)
|
||||
Projectile->SetStartTick(Server()->Tick() - 1);
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
|
@ -552,7 +554,10 @@ void CCharacter::FireWeapon()
|
|||
{
|
||||
float LaserReach = GetTuning(m_TuneZone)->m_LaserReach;
|
||||
|
||||
new CLaser(&GameServer()->m_World, m_Pos, Direction, LaserReach, m_pPlayer->GetCid(), WEAPON_SHOTGUN);
|
||||
CLaser *Laser = new CLaser(&GameServer()->m_World, m_Pos, Direction, LaserReach, m_pPlayer->GetCid(), WEAPON_SHOTGUN);
|
||||
if(EarlyFire)
|
||||
Laser->SetEvalTick(Server()->Tick() - 1);
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
break;
|
||||
|
@ -561,7 +566,7 @@ void CCharacter::FireWeapon()
|
|||
{
|
||||
int Lifetime = (int)(Server()->TickSpeed() * GetTuning(m_TuneZone)->m_GrenadeLifetime);
|
||||
|
||||
new CProjectile(
|
||||
CProjectile *Projectile = new CProjectile(
|
||||
GameWorld(),
|
||||
WEAPON_GRENADE, //Type
|
||||
m_pPlayer->GetCid(), //Owner
|
||||
|
@ -573,6 +578,8 @@ void CCharacter::FireWeapon()
|
|||
SOUND_GRENADE_EXPLODE, //SoundImpact
|
||||
MouseTarget // MouseTarget
|
||||
);
|
||||
if(EarlyFire)
|
||||
Projectile->SetStartTick(Server()->Tick() - 1);
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
|
@ -582,7 +589,10 @@ void CCharacter::FireWeapon()
|
|||
{
|
||||
float LaserReach = GetTuning(m_TuneZone)->m_LaserReach;
|
||||
|
||||
new CLaser(GameWorld(), m_Pos, Direction, LaserReach, m_pPlayer->GetCid(), WEAPON_LASER);
|
||||
CLaser *Laser = new CLaser(GameWorld(), m_Pos, Direction, LaserReach, m_pPlayer->GetCid(), WEAPON_LASER);
|
||||
if(EarlyFire)
|
||||
Laser->SetEvalTick(Server()->Tick() - 1);
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_LASER_FIRE, TeamMask()); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
}
|
||||
break;
|
||||
|
@ -602,6 +612,8 @@ void CCharacter::FireWeapon()
|
|||
}
|
||||
|
||||
m_AttackTick = Server()->Tick();
|
||||
if(EarlyFire)
|
||||
m_AttackTick--;
|
||||
|
||||
if(!m_ReloadTimer)
|
||||
{
|
||||
|
@ -671,6 +683,7 @@ void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
|||
|
||||
// copy new input
|
||||
mem_copy(&m_Input, pNewInput, sizeof(m_Input));
|
||||
m_NumInputs++;
|
||||
|
||||
// it is not allowed to aim in the center
|
||||
if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0)
|
||||
|
@ -679,28 +692,6 @@ void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
|||
mem_copy(&m_SavedInput, &m_Input, sizeof(m_SavedInput));
|
||||
}
|
||||
|
||||
void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
||||
{
|
||||
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
||||
mem_copy(&m_LatestInput, pNewInput, sizeof(m_LatestInput));
|
||||
m_NumInputs++;
|
||||
|
||||
// it is not allowed to aim in the center
|
||||
if(m_LatestInput.m_TargetX == 0 && m_LatestInput.m_TargetY == 0)
|
||||
m_LatestInput.m_TargetY = -1;
|
||||
|
||||
Antibot()->OnDirectInput(m_pPlayer->GetCid());
|
||||
|
||||
if(m_NumInputs > 1 && m_pPlayer->GetTeam() != TEAM_SPECTATORS)
|
||||
{
|
||||
HandleWeaponSwitch();
|
||||
FireWeapon();
|
||||
}
|
||||
|
||||
mem_copy(&m_LatestPrevPrevInput, &m_LatestPrevInput, sizeof(m_LatestInput));
|
||||
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
||||
}
|
||||
|
||||
void CCharacter::ReleaseHook()
|
||||
{
|
||||
m_Core.SetHookedPlayer(-1);
|
||||
|
@ -725,6 +716,27 @@ void CCharacter::ResetInput()
|
|||
m_LatestPrevInput = m_LatestInput = m_Input;
|
||||
}
|
||||
|
||||
void CCharacter::WeaponTick()
|
||||
{
|
||||
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
||||
mem_copy(&m_LatestInput, &m_Input, sizeof(m_LatestInput));
|
||||
|
||||
// it is not allowed to aim in the center
|
||||
if(m_LatestInput.m_TargetX == 0 && m_LatestInput.m_TargetY == 0)
|
||||
m_LatestInput.m_TargetY = -1;
|
||||
|
||||
Antibot()->OnDirectInput(m_pPlayer->GetCid());
|
||||
|
||||
if(m_NumInputs > 1 && m_pPlayer->GetTeam() != TEAM_SPECTATORS)
|
||||
{
|
||||
HandleWeaponSwitch();
|
||||
FireWeapon(true);
|
||||
}
|
||||
|
||||
mem_copy(&m_LatestPrevPrevInput, &m_LatestPrevInput, sizeof(m_LatestInput));
|
||||
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
||||
}
|
||||
|
||||
void CCharacter::PreTick()
|
||||
{
|
||||
if(m_StartTime > Server()->Tick())
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
void Reset() override;
|
||||
void Destroy() override;
|
||||
void PreTick();
|
||||
void WeaponTick();
|
||||
void Tick() override;
|
||||
void TickDeferred() override;
|
||||
void TickPaused() override;
|
||||
|
@ -61,11 +62,11 @@ public:
|
|||
void HandleJetpack();
|
||||
|
||||
void OnPredictedInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnDirectInput(CNetObj_PlayerInput *pNewInput);
|
||||
|
||||
void ReleaseHook();
|
||||
void ResetHook();
|
||||
void ResetInput();
|
||||
void FireWeapon();
|
||||
void FireWeapon(bool EarlyFire = false);
|
||||
|
||||
void Die(int Killer, int Weapon, bool SendKillMsg = true);
|
||||
bool TakeDamage(vec2 Force, int Dmg, int From, int Weapon);
|
||||
|
|
|
@ -35,6 +35,11 @@ CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEner
|
|||
DoBounce();
|
||||
}
|
||||
|
||||
void CLaser::SetEvalTick(int Tick)
|
||||
{
|
||||
m_EvalTick = Tick;
|
||||
}
|
||||
|
||||
bool CLaser::HitCharacter(vec2 From, vec2 To)
|
||||
{
|
||||
static const vec2 StackedLaserShotgunBugSpeed = vec2(-2147483648.0f, -2147483648.0f);
|
||||
|
@ -98,9 +103,11 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CLaser::DoBounce()
|
||||
void CLaser::DoBounce(bool EarlyTick)
|
||||
{
|
||||
m_EvalTick = Server()->Tick();
|
||||
if(EarlyTick)
|
||||
m_EvalTick--;
|
||||
|
||||
if(m_Energy < 0)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,13 @@
|
|||
class CLaser : public CEntity
|
||||
{
|
||||
public:
|
||||
CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner, int Type);
|
||||
CLaser(
|
||||
CGameWorld *pGameWorld,
|
||||
vec2 Pos,
|
||||
vec2 Direction,
|
||||
float StartEnergy,
|
||||
int Owner,
|
||||
int Type);
|
||||
|
||||
virtual void Reset() override;
|
||||
virtual void Tick() override;
|
||||
|
@ -20,7 +26,7 @@ public:
|
|||
|
||||
protected:
|
||||
bool HitCharacter(vec2 From, vec2 To);
|
||||
void DoBounce();
|
||||
void DoBounce(bool EarlyTick = false);
|
||||
|
||||
private:
|
||||
vec2 m_From;
|
||||
|
@ -42,6 +48,9 @@ private:
|
|||
bool m_TeleportCancelled;
|
||||
bool m_IsBlueTeleport;
|
||||
bool m_BelongsToPracticeTeam;
|
||||
|
||||
public:
|
||||
void SetEvalTick(int Tick);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,11 @@ CProjectile::CProjectile(
|
|||
GameWorld()->InsertEntity(this);
|
||||
}
|
||||
|
||||
void CProjectile::SetStartTick(int Tick)
|
||||
{
|
||||
m_StartTick = Tick;
|
||||
}
|
||||
|
||||
void CProjectile::Reset()
|
||||
{
|
||||
m_MarkedForDestroy = true;
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
vec2 m_InitDir;
|
||||
|
||||
public:
|
||||
void SetStartTick(int Tick);
|
||||
void SetBouncing(int Value);
|
||||
bool FillExtraInfoLegacy(CNetObj_DDRaceProjectile *pProj);
|
||||
void FillExtraInfo(CNetObj_DDNetProjectile *pProj);
|
||||
|
|
|
@ -1253,7 +1253,7 @@ void CGameContext::OnTick()
|
|||
|
||||
if(Server()->Tick() % (g_Config.m_SvAnnouncementInterval * Server()->TickSpeed() * 60) == 0)
|
||||
{
|
||||
const char *pLine = Server()->GetAnnouncementLine(g_Config.m_SvAnnouncementFileName);
|
||||
const char *pLine = Server()->GetAnnouncementLine();
|
||||
if(pLine)
|
||||
SendChat(-1, TEAM_ALL, pLine);
|
||||
}
|
||||
|
@ -1314,6 +1314,8 @@ void CGameContext::OnTick()
|
|||
}
|
||||
|
||||
// Server hooks
|
||||
|
||||
// Called on all incoming NETMSG_INPUT, reformats player flags for sixup compatibility
|
||||
void CGameContext::OnClientPrepareInput(int ClientId, void *pInput)
|
||||
{
|
||||
auto *pPlayerInput = (CNetObj_PlayerInput *)pInput;
|
||||
|
@ -1321,10 +1323,11 @@ void CGameContext::OnClientPrepareInput(int ClientId, void *pInput)
|
|||
pPlayerInput->m_PlayerFlags = PlayerFlags_SevenToSix(pPlayerInput->m_PlayerFlags);
|
||||
}
|
||||
|
||||
void CGameContext::OnClientDirectInput(int ClientId, void *pInput)
|
||||
// Called on all incoming NETMSG_INPUT, only sets player flags and tracks afk status
|
||||
void CGameContext::OnClientFreshInput(int ClientId, void *pInput)
|
||||
{
|
||||
if(!m_World.m_Paused)
|
||||
m_apPlayers[ClientId]->OnDirectInput((CNetObj_PlayerInput *)pInput);
|
||||
m_apPlayers[ClientId]->OnPlayerFreshInput((CNetObj_PlayerInput *)pInput);
|
||||
|
||||
int Flags = ((CNetObj_PlayerInput *)pInput)->m_PlayerFlags;
|
||||
if((Flags & 256) || (Flags & 512))
|
||||
|
@ -1333,26 +1336,11 @@ void CGameContext::OnClientDirectInput(int ClientId, void *pInput)
|
|||
}
|
||||
}
|
||||
|
||||
// Called once per input that happens on this tick.
|
||||
// pInput is nullptr if the client did not send any fresh input this tick.
|
||||
void CGameContext::OnClientPredictedInput(int ClientId, void *pInput)
|
||||
{
|
||||
// early return if no input at all has been sent by a player
|
||||
if(pInput == nullptr && !m_aPlayerHasInput[ClientId])
|
||||
return;
|
||||
|
||||
// set to last sent input when no new input has been sent
|
||||
CNetObj_PlayerInput *pApplyInput = (CNetObj_PlayerInput *)pInput;
|
||||
if(pApplyInput == nullptr)
|
||||
{
|
||||
pApplyInput = &m_aLastPlayerInput[ClientId];
|
||||
}
|
||||
|
||||
if(!m_World.m_Paused)
|
||||
m_apPlayers[ClientId]->OnPredictedInput(pApplyInput);
|
||||
}
|
||||
|
||||
void CGameContext::OnClientPredictedEarlyInput(int ClientId, void *pInput)
|
||||
{
|
||||
// early return if no input at all has been sent by a player
|
||||
// early return if no input has ever been sent by the player
|
||||
if(pInput == nullptr && !m_aPlayerHasInput[ClientId])
|
||||
return;
|
||||
|
||||
|
@ -1364,16 +1352,12 @@ void CGameContext::OnClientPredictedEarlyInput(int ClientId, void *pInput)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Store input in this function and not in `OnClientPredictedInput`,
|
||||
// because this function is called on all inputs, while
|
||||
// `OnClientPredictedInput` is only called on the first input of each
|
||||
// tick.
|
||||
mem_copy(&m_aLastPlayerInput[ClientId], pApplyInput, sizeof(m_aLastPlayerInput[ClientId]));
|
||||
m_aPlayerHasInput[ClientId] = true;
|
||||
}
|
||||
|
||||
if(!m_World.m_Paused)
|
||||
m_apPlayers[ClientId]->OnPredictedEarlyInput(pApplyInput);
|
||||
m_apPlayers[ClientId]->OnPlayerInput(pApplyInput);
|
||||
|
||||
if(m_TeeHistorianActive)
|
||||
{
|
||||
|
@ -3643,6 +3627,7 @@ void CGameContext::OnConsoleInit()
|
|||
Console()->Register("set_team_all", "i[team-id]", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team");
|
||||
Console()->Register("hot_reload", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConHotReload, this, "Reload the map while preserving the state of tees and teams");
|
||||
Console()->Register("reload_censorlist", "", CFGFLAG_SERVER, ConReloadCensorlist, this, "Reload the censorlist");
|
||||
Console()->Register("reload_announcement", "", CFGFLAG_SERVER, ConReloadAnnouncement, this, "Reload the announcements");
|
||||
|
||||
Console()->Register("add_vote", "s[name] r[command]", CFGFLAG_SERVER, ConAddVote, this, "Add a voting option");
|
||||
Console()->Register("remove_vote", "r[name]", CFGFLAG_SERVER, ConRemoveVote, this, "remove a voting option");
|
||||
|
|
|
@ -320,9 +320,8 @@ public:
|
|||
void OnClientEnter(int ClientId) override;
|
||||
void OnClientDrop(int ClientId, const char *pReason) override;
|
||||
void OnClientPrepareInput(int ClientId, void *pInput) override;
|
||||
void OnClientDirectInput(int ClientId, void *pInput) override;
|
||||
void OnClientFreshInput(int ClientId, void *pInput) override;
|
||||
void OnClientPredictedInput(int ClientId, void *pInput) override;
|
||||
void OnClientPredictedEarlyInput(int ClientId, void *pInput) override;
|
||||
|
||||
void TeehistorianRecordAntibot(const void *pData, int DataSize) override;
|
||||
void TeehistorianRecordPlayerJoin(int ClientId, bool Sixup) override;
|
||||
|
@ -516,6 +515,7 @@ private:
|
|||
static void ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
static void ConReloadCensorlist(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConReloadAnnouncement(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
CCharacter *GetPracticeCharacter(IConsole::IResult *pResult);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "entity.h"
|
||||
#include "gamecontext.h"
|
||||
#include "gamecontroller.h"
|
||||
#include "player.h"
|
||||
|
||||
#include <engine/shared/config.h>
|
||||
|
||||
|
@ -214,6 +215,17 @@ void CGameWorld::Tick()
|
|||
if(GameServer()->m_pController->IsForceBalanced())
|
||||
GameServer()->SendChat(-1, TEAM_ALL, "Teams have been balanced");
|
||||
|
||||
// This is placed here so that certain weapon physics can happen before the regular Charecter Tick() to preserve physics accuracy.
|
||||
// It is done in client order to preserve previous behavior.
|
||||
for(auto &pPlayer : GameServer()->m_apPlayers)
|
||||
{
|
||||
if(!pPlayer)
|
||||
continue;
|
||||
CCharacter *pChar = pPlayer->GetCharacter();
|
||||
if(pChar)
|
||||
pChar->WeaponTick();
|
||||
}
|
||||
|
||||
// update all objects
|
||||
for(int i = 0; i < NUM_ENTTYPES; i++)
|
||||
{
|
||||
|
|
|
@ -500,8 +500,13 @@ void CPlayer::OnDisconnect()
|
|||
m_Moderating = false;
|
||||
}
|
||||
|
||||
void CPlayer::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
||||
void CPlayer::OnPlayerInput(CNetObj_PlayerInput *pNewInput)
|
||||
{
|
||||
m_PlayerFlags = pNewInput->m_PlayerFlags;
|
||||
|
||||
if(!m_pCharacter && m_Team != TEAM_SPECTATORS && (pNewInput->m_Fire & 1))
|
||||
m_Spawning = true;
|
||||
|
||||
// skip the input if chat is active
|
||||
if((m_PlayerFlags & PLAYERFLAG_CHATTING) && (pNewInput->m_PlayerFlags & PLAYERFLAG_CHATTING))
|
||||
return;
|
||||
|
@ -520,7 +525,8 @@ void CPlayer::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
|||
GameServer()->SendBroadcast("This server uses an experimental translation from Teeworlds 0.7 to 0.6. Please report bugs on ddnet.org/discord", m_ClientId);
|
||||
}
|
||||
|
||||
void CPlayer::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
||||
// Afk player tracking
|
||||
void CPlayer::OnPlayerFreshInput(CNetObj_PlayerInput *pNewInput)
|
||||
{
|
||||
Server()->SetClientFlags(m_ClientId, pNewInput->m_PlayerFlags);
|
||||
|
||||
|
@ -541,21 +547,6 @@ void CPlayer::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
|||
}
|
||||
}
|
||||
|
||||
void CPlayer::OnPredictedEarlyInput(CNetObj_PlayerInput *pNewInput)
|
||||
{
|
||||
m_PlayerFlags = pNewInput->m_PlayerFlags;
|
||||
|
||||
if(!m_pCharacter && m_Team != TEAM_SPECTATORS && (pNewInput->m_Fire & 1))
|
||||
m_Spawning = true;
|
||||
|
||||
// skip the input if chat is active
|
||||
if(m_PlayerFlags & PLAYERFLAG_CHATTING)
|
||||
return;
|
||||
|
||||
if(m_pCharacter && !m_Paused)
|
||||
m_pCharacter->OnDirectInput(pNewInput);
|
||||
}
|
||||
|
||||
int CPlayer::GetClientVersion() const
|
||||
{
|
||||
return m_pGameServer->GetClientVersion(m_ClientId);
|
||||
|
|
|
@ -57,9 +57,8 @@ public:
|
|||
void Snap(int SnappingClient);
|
||||
void FakeSnap();
|
||||
|
||||
void OnDirectInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnPredictedInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnPredictedEarlyInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnPlayerFreshInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnPlayerInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnDisconnect();
|
||||
|
||||
void KillCharacter(int Weapon = WEAPON_GAME, bool SendKillMsg = true);
|
||||
|
|
|
@ -1028,7 +1028,7 @@ bool CScoreWorker::ShowTop(IDbConnection *pSqlServer, const ISqlData *pGameData,
|
|||
|
||||
if(!g_Config.m_SvRegionalRankings)
|
||||
{
|
||||
str_copy(pResult->m_Data.m_aaMessages[Line], "----------------------------------------", sizeof(pResult->m_Data.m_aaMessages[Line]));
|
||||
str_copy(pResult->m_Data.m_aaMessages[Line], "-----------------------------------------", sizeof(pResult->m_Data.m_aaMessages[Line]));
|
||||
return !End;
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1146,7 @@ bool CScoreWorker::ShowTeamTop5(IDbConnection *pSqlServer, const ISqlData *pGame
|
|||
}
|
||||
}
|
||||
|
||||
str_copy(paMessages[Line], "-------------------------------", sizeof(paMessages[Line]));
|
||||
str_copy(paMessages[Line], "---------------------------------", sizeof(paMessages[Line]));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1230,7 +1230,7 @@ bool CScoreWorker::ShowPlayerTeamTop5(IDbConnection *pSqlServer, const ISqlData
|
|||
break;
|
||||
}
|
||||
}
|
||||
str_copy(paMessages[Line], "-------------------------------", sizeof(paMessages[Line]));
|
||||
str_copy(paMessages[Line], "---------------------------------", sizeof(paMessages[Line]));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1352,7 +1352,7 @@ bool CScoreWorker::ShowTimes(IDbConnection *pSqlServer, const ISqlData *pGameDat
|
|||
{
|
||||
return true;
|
||||
}
|
||||
str_copy(paMessages[Line], "----------------------------------------------------", sizeof(paMessages[Line]));
|
||||
str_copy(paMessages[Line], "-------------------------------------------", sizeof(paMessages[Line]));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ TEST_P(SingleScore, Top)
|
|||
ExpectLines(m_pPlayerResult,
|
||||
{"------------ Global Top ------------",
|
||||
"1. nameless tee Time: 01:40.00",
|
||||
"----------------------------------------"});
|
||||
"-----------------------------------------"});
|
||||
}
|
||||
|
||||
TEST_P(SingleScore, RankRegional)
|
||||
|
@ -197,7 +197,7 @@ TEST_P(SingleScore, TopServer)
|
|||
ExpectLines(m_pPlayerResult,
|
||||
{"------------ Global Top ------------",
|
||||
"1. nameless tee Time: 01:40.00",
|
||||
"----------------------------------------"});
|
||||
"-----------------------------------------"});
|
||||
}
|
||||
|
||||
TEST_P(SingleScore, RankServerRegional)
|
||||
|
@ -264,7 +264,7 @@ TEST_P(SingleScore, TimesExists)
|
|||
|
||||
str_copy(aBuf, m_pPlayerResult->m_Data.m_aaMessages[1] + str_length(m_pPlayerResult->m_Data.m_aaMessages[1]) - 10, 11);
|
||||
EXPECT_STREQ(aBuf, ", 01:40.00");
|
||||
EXPECT_STREQ(m_pPlayerResult->m_Data.m_aaMessages[2], "----------------------------------------------------");
|
||||
EXPECT_STREQ(m_pPlayerResult->m_Data.m_aaMessages[2], "-------------------------------------------");
|
||||
for(int i = 3; i < CScorePlayerResult::MAX_MESSAGES; i++)
|
||||
{
|
||||
EXPECT_STREQ(m_pPlayerResult->m_Data.m_aaMessages[i], "");
|
||||
|
@ -321,7 +321,7 @@ TEST_P(TeamScore, All)
|
|||
ExpectLines(m_pPlayerResult,
|
||||
{"------- Team Top 5 -------",
|
||||
"1. brainless tee & nameless tee Team Time: 01:40.00",
|
||||
"-------------------------------"});
|
||||
"---------------------------------"});
|
||||
}
|
||||
|
||||
TEST_P(TeamScore, PlayerExists)
|
||||
|
@ -331,7 +331,7 @@ TEST_P(TeamScore, PlayerExists)
|
|||
ExpectLines(m_pPlayerResult,
|
||||
{"------- Team Top 5 -------",
|
||||
"1. brainless tee & nameless tee Team Time: 01:40.00",
|
||||
"-------------------------------"});
|
||||
"---------------------------------"});
|
||||
}
|
||||
|
||||
TEST_P(TeamScore, PlayerDoesntExist)
|
||||
|
@ -349,7 +349,7 @@ TEST_P(TeamScore, RankUpdates)
|
|||
ExpectLines(m_pPlayerResult,
|
||||
{"------- Team Top 5 -------",
|
||||
"1. brainless tee & nameless tee Team Time: 01:38.00",
|
||||
"-------------------------------"});
|
||||
"---------------------------------"});
|
||||
}
|
||||
|
||||
struct MapInfo : public Score
|
||||
|
|
Loading…
Reference in a new issue