130 changes: 57 additions & 73 deletions src/game/server/ddracechat.cpp
Expand Up @@ -244,69 +244,25 @@ void CGameContext::ConRules(IConsole::IResult *pResult, void *pUserData)
"Be nice.");
Printed = true;
}
if (g_Config.m_SvRulesLine1[0])
#define _RL(n) g_Config.m_SvRulesLine ## n
char *pRuleLines[] = {
_RL(1), _RL(2), _RL(3), _RL(4), _RL(5),
_RL(6), _RL(7), _RL(8), _RL(9), _RL(10),
};
for(unsigned i = 0; i < sizeof(pRuleLines) / sizeof(pRuleLines[0]); i++)
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine1);
Printed = true;
}
if (g_Config.m_SvRulesLine2[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine2);
Printed = true;
}
if (g_Config.m_SvRulesLine3[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine3);
Printed = true;
}
if (g_Config.m_SvRulesLine4[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine4);
Printed = true;
}
if (g_Config.m_SvRulesLine5[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine5);
Printed = true;
}
if (g_Config.m_SvRulesLine6[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine6);
Printed = true;
}
if (g_Config.m_SvRulesLine7[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine7);
Printed = true;
}
if (g_Config.m_SvRulesLine8[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine8);
Printed = true;
}
if (g_Config.m_SvRulesLine9[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine9);
Printed = true;
}
if (g_Config.m_SvRulesLine10[0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
g_Config.m_SvRulesLine10);
Printed = true;
if(pRuleLines[i][0])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,
"rules", pRuleLines[i]);
Printed = true;
}
}
if (!Printed)
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "rules",
"No Rules Defined, Kill em all!!");
}
}

void CGameContext::ConToggleSpec(IConsole::IResult *pResult, void *pUserData)
Expand Down Expand Up @@ -1225,32 +1181,60 @@ void CGameContext::ConSetTimerType(IConsole::IResult *pResult, void *pUserData)

const char msg[3][128] = {"game/round timer.", "broadcast.", "both game/round timer and broadcast."};
char aBuf[128];
if(pPlayer->m_TimerType <= 2 && pPlayer->m_TimerType >= 0)
str_format(aBuf, sizeof(aBuf), "Timer is displayed in", msg[pPlayer->m_TimerType]);
else if(pPlayer->m_TimerType == 3)
if(pPlayer->m_TimerType <= CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST && pPlayer->m_TimerType >= CPlayer::TIMERTYPE_GAMETIMER)
str_format(aBuf, sizeof(aBuf), "Timer is displayed in %s", msg[pPlayer->m_TimerType]);
else if(pPlayer->m_TimerType == CPlayer::TIMERTYPE_NONE)
str_format(aBuf, sizeof(aBuf), "Timer isn't displayed.");

int OldType = pPlayer->m_TimerType;

if(pResult->NumArguments() == 0) {
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,"timer",aBuf);
return;
}
else if(str_comp_nocase(pResult->GetString(0), "gametimer") == 0) {
pSelf->SendBroadcast("", pResult->m_ClientID);
pPlayer->m_TimerType = 0;
else if(str_comp_nocase(pResult->GetString(0), "gametimer") == 0)
{
if(pPlayer->m_ClientVersion >= VERSION_DDNET_GAMETICK)
pPlayer->m_TimerType = CPlayer::TIMERTYPE_GAMETIMER;
else
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "timer", "gametimer is not supported by your client.");
}
else if(str_comp_nocase(pResult->GetString(0), "broadcast") == 0)
pPlayer->m_TimerType = 1;
pPlayer->m_TimerType = CPlayer::TIMERTYPE_BROADCAST;
else if(str_comp_nocase(pResult->GetString(0), "both") == 0)
pPlayer->m_TimerType = 2;
{
if(pPlayer->m_ClientVersion >= VERSION_DDNET_GAMETICK)
pPlayer->m_TimerType = CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST;
else
{
pPlayer->m_TimerType = CPlayer::TIMERTYPE_BROADCAST;
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "timer", "gametimer is not supported by your client.");
}
}
else if(str_comp_nocase(pResult->GetString(0), "none") == 0)
pPlayer->m_TimerType = 3;
else if(str_comp_nocase(pResult->GetString(0), "cycle") == 0) {
if(pPlayer->m_TimerType < 3)
pPlayer->m_TimerType++;
else if(pPlayer->m_TimerType == 3)
pPlayer->m_TimerType = 0;
pPlayer->m_TimerType = CPlayer::TIMERTYPE_NONE;
else if(str_comp_nocase(pResult->GetString(0), "cycle") == 0)
{
if(pPlayer->m_ClientVersion >= VERSION_DDNET_GAMETICK)
{
if(pPlayer->m_TimerType < CPlayer::TIMERTYPE_NONE)
pPlayer->m_TimerType++;
else if(pPlayer->m_TimerType == CPlayer::TIMERTYPE_NONE)
pPlayer->m_TimerType = CPlayer::TIMERTYPE_GAMETIMER;
}
else
{
if(pPlayer->m_TimerType < CPlayer::TIMERTYPE_NONE)
pPlayer->m_TimerType = CPlayer::TIMERTYPE_NONE;
else if(pPlayer->m_TimerType == CPlayer::TIMERTYPE_NONE)
pPlayer->m_TimerType = CPlayer::TIMERTYPE_BROADCAST;
}
}
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,"timer",aBuf);

if((OldType == CPlayer::TIMERTYPE_BROADCAST || OldType == CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST) && (pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER || pPlayer->m_TimerType == CPlayer::TIMERTYPE_NONE))
pSelf->SendBroadcast("", pResult->m_ClientID);

pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "timer", aBuf);
}

void CGameContext::ConRescue(IConsole::IResult *pResult, void *pUserData)
Expand Down
6 changes: 3 additions & 3 deletions src/game/server/entities/character.cpp
Expand Up @@ -665,7 +665,7 @@ void CCharacter::RemoveNinja()
m_Ninja.m_CurrentMoveTime = 0;
m_aWeapons[WEAPON_NINJA].m_Got = false;
m_Core.m_ActiveWeapon = m_LastWeapon;

SetWeapon(m_Core.m_ActiveWeapon);
}

Expand Down Expand Up @@ -1211,7 +1211,7 @@ void CCharacter::HandleBroadcast()
m_CpLastBroadcast = m_CpActive;
m_LastBroadcast = Server()->Tick();
}
else if ((m_pPlayer->m_TimerType == 1 || m_pPlayer->m_TimerType == 2) && m_DDRaceState == DDRACE_STARTED && m_LastBroadcast + Server()->TickSpeed() * g_Config.m_SvTimeInBroadcastInterval <= Server()->Tick())
else if ((m_pPlayer->m_TimerType == CPlayer::TIMERTYPE_BROADCAST || m_pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST) && m_DDRaceState == DDRACE_STARTED && m_LastBroadcast + Server()->TickSpeed() * g_Config.m_SvTimeInBroadcastInterval <= Server()->Tick())
{
char aBuftime[64];
int IntTime = (int)((float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed()));
Expand Down Expand Up @@ -2124,7 +2124,7 @@ void CCharacter::GiveWeapon(int Weapon, bool Remove)
GiveNinja();
return;
}

if (Remove)
{
if (GetActiveWeapon()== Weapon)
Expand Down
64 changes: 62 additions & 2 deletions src/game/server/gamecontext.cpp
Expand Up @@ -1136,7 +1136,64 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
Console()->SetAccessLevel(IConsole::ACCESS_LEVEL_USER);
Console()->SetPrintOutputLevel(m_ChatPrintCBIndex, 0);

Console()->ExecuteLine(pMsg->m_pMessage + 1, ClientID);
bool InterpretSemicolons = !(pPlayer->m_PlayerFlags & PLAYERFLAG_CHATTING);
Console()->ExecuteLine(pMsg->m_pMessage + 1, ClientID, InterpretSemicolons);
// m_apPlayers[ClientID] can be NULL, if the player used a
// timeout code and replaced another client.
if(InterpretSemicolons && m_apPlayers[ClientID] && !m_apPlayers[ClientID]->m_SentSemicolonTip)
{
bool FoundSemicolons = false;

const char *pStr = pMsg->m_pMessage + 1;
int Length = str_length(pStr);
bool InString = false;
bool Escape = false;
for(int i = 0; i < Length; i++)
{
char c = pStr[i];
if(InString)
{
if(Escape)
{
Escape = false;
if(c == '\\' || c == '"')
{
continue;
}
}
else if(c == '\\')
{
Escape = true;
}
else if(c == '"')
{
InString = false;
}
}
else
{
if(c == '"')
{
InString = true;
}
else if(c == ';')
{
FoundSemicolons = true;
break;
}
}
}
static const char s_aPrefix[] = "mc;";
static const int s_PrefixLength = str_length(s_aPrefix);
if(FoundSemicolons && !(Length >= s_PrefixLength && str_comp_num(pStr, s_aPrefix, s_PrefixLength) == 0))
{
SendChatTarget(ClientID, "Usage of semicolons without /mc is deprecated");
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "Try changing your bind to '/mc;%s'", pStr);
SendChatTarget(ClientID, aBuf);
m_apPlayers[ClientID]->m_SentSemicolonTip = true;
}
}
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "%d used %s", ClientID, pMsg->m_pMessage);
Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "chat-command", aBuf);
Expand Down Expand Up @@ -1504,7 +1561,10 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
}
else if(pPlayer->m_ClientVersion < Version)
pPlayer->m_ClientVersion = Version;


if(pPlayer->m_ClientVersion >= VERSION_DDNET_GAMETICK)
pPlayer->m_TimerType = g_Config.m_SvDefaultTimerType;

dbg_msg("ddnet", "%d using Custom Client %d", ClientID, pPlayer->m_ClientVersion);

//first update his teams state
Expand Down
14 changes: 9 additions & 5 deletions src/game/server/gamecontroller.cpp
Expand Up @@ -770,18 +770,22 @@ void IGameController::Snap(int SnappingClient)
CPlayer *pPlayer = SnappingClient > -1 ? GameServer()->m_apPlayers[SnappingClient] : 0;
CPlayer *pPlayer2;

if(pPlayer && (pPlayer->m_TimerType == 0 || pPlayer->m_TimerType == 2))
if(pPlayer && (pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER || pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST) && pPlayer->m_ClientVersion >= VERSION_DDNET_GAMETICK)
{
if((pPlayer->GetTeam() == -1 || pPlayer->m_Paused)
&& pPlayer->m_SpectatorID != SPEC_FREEVIEW
&& (pPlayer2 = GameServer()->m_apPlayers[pPlayer->m_SpectatorID]))
{
if((pChr = pPlayer2->GetCharacter()))
pGameInfoObj->m_RoundStartTick = (pChr->m_DDRaceState == DDRACE_STARTED)?pChr->m_StartTime:m_RoundStartTick;
if((pChr = pPlayer2->GetCharacter()) && pChr->m_DDRaceState == DDRACE_STARTED)
{
pGameInfoObj->m_WarmupTimer = -pChr->m_StartTime;
pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_RACETIME;
}
}
else if((pChr = pPlayer->GetCharacter()))
else if((pChr = pPlayer->GetCharacter()) && pChr->m_DDRaceState == DDRACE_STARTED)
{
pGameInfoObj->m_RoundStartTick = (pChr->m_DDRaceState == DDRACE_STARTED)?pChr->m_StartTime:m_RoundStartTick;
pGameInfoObj->m_WarmupTimer = -pChr->m_StartTime;
pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_RACETIME;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/server/player.cpp
Expand Up @@ -64,7 +64,7 @@ void CPlayer::Reset()
m_Sent2ndAfkWarning = 0;
m_ChatScore = 0;
m_EyeEmote = true;
m_TimerType = g_Config.m_SvDefaultTimerType;
m_TimerType = (g_Config.m_SvDefaultTimerType == CPlayer::TIMERTYPE_GAMETIMER || g_Config.m_SvDefaultTimerType == CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST) ? CPlayer::TIMERTYPE_BROADCAST : g_Config.m_SvDefaultTimerType;
m_DefEmote = EMOTE_NORMAL;
m_Afk = false;
m_LastWhisperTo = -1;
Expand Down
9 changes: 9 additions & 0 deletions src/game/server/player.h
Expand Up @@ -96,6 +96,7 @@ class CPlayer
int m_LastActionTick;
bool m_StolenSkin;
int m_TeamChangeTick;
bool m_SentSemicolonTip;
struct
{
int m_TargetX;
Expand Down Expand Up @@ -138,6 +139,14 @@ class CPlayer
PAUSED_PAUSED,
PAUSED_FORCE
};

enum
{
TIMERTYPE_GAMETIMER=0,
TIMERTYPE_BROADCAST,
TIMERTYPE_GAMETIMER_AND_BROADCAST,
TIMERTYPE_NONE,
};

int m_Paused;
bool m_DND;
Expand Down
6 changes: 3 additions & 3 deletions src/game/version.h
Expand Up @@ -3,8 +3,8 @@
#ifndef GAME_VERSION_H
#define GAME_VERSION_H
#include "generated/nethash.cpp"
#define GAME_VERSION "0.6.3, 10.3.5"
#define GAME_VERSION "0.6.3, 10.4.3"
#define GAME_NETVERSION "0.6 626fce9a778df4d4"
static const char GAME_RELEASE_VERSION[8] = "10.3.5";
#define CLIENT_VERSIONNR 10035
static const char GAME_RELEASE_VERSION[8] = "10.4.3";
#define CLIENT_VERSIONNR 10043
#endif
8 changes: 4 additions & 4 deletions src/versionsrv/versionsrv.cpp
Expand Up @@ -67,13 +67,13 @@ void BuildPackets()

void ReadNews()
{
IOHANDLE newsFile = io_open("news", IOFLAG_READ);
if (!newsFile)
IOHANDLE NewsFile = io_open("news", IOFLAG_READ);
if (!NewsFile)
return;

io_read(newsFile, m_aNews, NEWS_SIZE);
io_read(NewsFile, m_aNews, NEWS_SIZE);

io_close(newsFile);
io_close(NewsFile);
}

void ReadServerList()
Expand Down