ddnet/src/game/server/ddracecommands.cpp

420 lines
13 KiB
C++
Raw Normal View History

/* (c) Shereef Marzouk. See "licence DDRace.txt" and the readme.txt in the root of the distribution for more information. */
2010-11-13 15:31:13 +00:00
#include "gamecontext.h"
2010-11-13 15:41:43 +00:00
#include <engine/shared/config.h>
#include <engine/server/server.h>
#include <game/server/teams.h>
#include <game/server/gamemodes/DDRace.h>
#include <game/version.h>
#include <game/generated/nethash.cpp>
#if defined(CONF_SQL)
#include <game/server/score/sql_score.h>
#endif
2010-11-13 15:31:13 +00:00
2011-08-26 18:03:30 +00:00
bool CheckClientID(int ClientID);
void CGameContext::ConGoLeft(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
pSelf->MoveCharacter(pResult->m_ClientID, -1, 0);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConGoRight(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
pSelf->MoveCharacter(pResult->m_ClientID, 1, 0);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConGoDown(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
pSelf->MoveCharacter(pResult->m_ClientID, 0, 1);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConGoUp(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
pSelf->MoveCharacter(pResult->m_ClientID, 0, -1);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConMove(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
pSelf->MoveCharacter(pResult->m_ClientID, pResult->GetInteger(0), pResult->GetInteger(1));
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConMoveRaw(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
pSelf->MoveCharacter(pResult->m_ClientID, pResult->GetInteger(0), pResult->GetInteger(1), true);
2010-11-13 15:31:13 +00:00
}
void CGameContext::MoveCharacter(int ClientID, int X, int Y, bool Raw)
2010-11-13 15:31:13 +00:00
{
CCharacter* pChr = GetPlayerChar(ClientID);
2010-11-13 15:31:13 +00:00
if(!pChr)
return;
2011-01-29 00:59:50 +00:00
pChr->Core()->m_Pos.x += ((Raw) ? 1 : 32) * X;
pChr->Core()->m_Pos.y += ((Raw) ? 1 : 32) * Y;
pChr->m_DDRaceState = DDRACE_CHEAT;
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConKillPlayer(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
int Victim = pResult->GetInteger(0);
2010-11-13 15:31:13 +00:00
if(pSelf->m_apPlayers[Victim])
{
pSelf->m_apPlayers[Victim]->KillCharacter(WEAPON_GAME);
2011-01-26 21:09:54 +00:00
char aBuf[512];
2011-08-26 18:03:30 +00:00
str_format(aBuf, sizeof(aBuf), "%s was killed by %s", pSelf->Server()->ClientName(Victim), pSelf->Server()->ClientName(pResult->m_ClientID));
2011-01-26 21:09:54 +00:00
pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
2010-11-13 15:31:13 +00:00
}
}
void CGameContext::ConNinja(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_NINJA, false);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConSuper(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
CCharacter* pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
2011-01-26 21:09:54 +00:00
if(pChr && !pChr->m_Super)
{
pChr->m_Super = true;
pChr->UnFreeze();
pChr->m_TeamBeforeSuper = pChr->Team();
2011-08-26 18:03:30 +00:00
pChr->Teams()->SetCharacterTeam(pResult->m_ClientID, TEAM_SUPER);
pChr->m_DDRaceState = DDRACE_CHEAT;
2010-11-13 15:31:13 +00:00
}
}
void CGameContext::ConUnSuper(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
CCharacter* pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
2011-01-26 21:09:54 +00:00
if(pChr && pChr->m_Super)
2010-11-13 15:31:13 +00:00
{
2011-01-26 21:09:54 +00:00
pChr->m_Super = false;
2011-08-26 18:03:30 +00:00
pChr->Teams()->SetForceCharacterTeam(pResult->m_ClientID, pChr->m_TeamBeforeSuper);
2010-11-13 15:31:13 +00:00
}
}
void CGameContext::ConShotgun(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_SHOTGUN, false);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConGrenade(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_GRENADE, false);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConRifle(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_RIFLE, false);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConWeapons(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, -1, false);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConUnShotgun(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_SHOTGUN, true);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConUnGrenade(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_GRENADE, true);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConUnRifle(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_RIFLE, true);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConUnWeapons(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, -1, true);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConAddWeapon(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, pResult->GetInteger(0), false);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConRemoveWeapon(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ModifyWeapons(pResult, pUserData, pResult->GetInteger(0), true);
2010-11-13 15:31:13 +00:00
}
void CGameContext::ModifyWeapons(IConsole::IResult *pResult, void *pUserData, int Weapon, bool Remove)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
int ClientID = pResult->m_ClientID;
2010-11-13 15:31:13 +00:00
if(clamp(Weapon, -1, NUM_WEAPONS - 1) != Weapon)
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "invalid weapon id");
2010-11-13 15:31:13 +00:00
return;
}
CCharacter* pChr = GetPlayerChar(ClientID);
2010-11-13 15:31:13 +00:00
if(!pChr)
return;
2010-11-13 15:31:13 +00:00
if(Weapon == -1)
{
2011-01-29 00:59:50 +00:00
if(Remove && (pChr->GetActiveWeapon() == WEAPON_SHOTGUN || pChr->GetActiveWeapon() == WEAPON_GRENADE || pChr->GetActiveWeapon() == WEAPON_RIFLE))
pChr->SetActiveWeapon(WEAPON_GUN);
2010-11-13 15:31:13 +00:00
if(Remove)
{
2011-01-29 00:59:50 +00:00
pChr->SetWeaponGot(WEAPON_SHOTGUN, false);
pChr->SetWeaponGot(WEAPON_GRENADE, false);
pChr->SetWeaponGot(WEAPON_RIFLE, false);
2010-11-13 15:31:13 +00:00
}
else
pChr->GiveAllWeapons();
2010-11-13 15:31:13 +00:00
}
else if(Weapon != WEAPON_NINJA)
{
2011-01-29 00:59:50 +00:00
if(Remove && pChr->GetActiveWeapon() == Weapon)
pChr->SetActiveWeapon(WEAPON_GUN);
2010-11-13 15:31:13 +00:00
if(Remove)
2011-01-29 00:59:50 +00:00
pChr->SetWeaponGot(Weapon, false);
2010-11-13 15:31:13 +00:00
else
pChr->GiveWeapon(Weapon, -1);
}
else
{
if(Remove)
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "you can't remove ninja");
2010-11-13 15:31:13 +00:00
return;
}
2010-11-13 15:31:13 +00:00
pChr->GiveNinja();
}
pChr->m_DDRaceState = DDRACE_CHEAT;
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConTeleport(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
2010-11-13 15:31:13 +00:00
int TeleTo = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
if(pSelf->m_apPlayers[TeleTo])
{
{
2011-08-26 18:03:30 +00:00
CCharacter* pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
2011-01-26 21:09:54 +00:00
if(pChr)
2010-11-13 15:31:13 +00:00
{
2011-01-29 00:59:50 +00:00
pChr->Core()->m_Pos = pSelf->m_apPlayers[TeleTo]->m_ViewPos;
pChr->m_DDRaceState = DDRACE_CHEAT;
2010-11-13 15:31:13 +00:00
}
}
}
}
void CGameContext::ConKill(IConsole::IResult *pResult, void *pUserData)
2010-11-13 15:31:13 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID];
2010-11-13 15:31:13 +00:00
if(!pPlayer || (pPlayer->m_LastKill && pPlayer->m_LastKill + pSelf->Server()->TickSpeed() * g_Config.m_SvKillDelay > pSelf->Server()->Tick()))
2010-11-13 15:31:13 +00:00
return;
pPlayer->m_LastKill = pSelf->Server()->Tick();
2010-11-13 15:31:13 +00:00
pPlayer->KillCharacter(WEAPON_SELF);
//pPlayer->m_RespawnTick = pSelf->Server()->Tick() + pSelf->Server()->TickSpeed() * g_Config.m_SvSuicidePenalty;
2010-11-13 15:31:13 +00:00
}
void CGameContext::ConForcePause(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
CServer* pServ = (CServer*)pSelf->Server();
int Victim = pResult->GetInteger(0);
int Seconds = 0;
char aBuf[128];
2011-08-26 18:03:30 +00:00
if(pResult->NumArguments() > 0 && pResult->m_ClientID < 0)
Seconds = clamp(pResult->GetInteger(0), 0, 15);
CPlayer *pPlayer = pSelf->m_apPlayers[Victim];
2011-08-26 18:03:30 +00:00
if(!pPlayer || (!Seconds && pResult->m_ClientID >= 0))
return;
CCharacter* pChr = pPlayer->GetCharacter();
2011-08-26 18:03:30 +00:00
if(!pPlayer->GetTeam() && pChr && !pPlayer->m_InfoSaved && pResult->m_ClientID < 0)
{
pPlayer->SaveCharacter();
pPlayer->m_InfoSaved = true;
pPlayer->SetTeam(TEAM_SPECTATORS);
pPlayer->m_ForcePauseTime = Seconds*pServ->TickSpeed();
}
else
{
pPlayer->m_ForcePauseTime = Seconds*pServ->TickSpeed();
}
2011-08-26 18:03:30 +00:00
if(pResult->m_ClientID < 0)
str_format(aBuf, sizeof(aBuf), "'%s' has been force-paused for %d seconds", pServ->ClientName(Victim), Seconds);
else
2011-08-26 18:03:30 +00:00
str_format(aBuf, sizeof(aBuf), "Force-pause of '%s' have been removed by '%s'", pServ->ClientName(Victim), pServ->ClientName(pResult->m_ClientID));
pSelf->SendChat(-1, CHAT_ALL, aBuf);
}
void CGameContext::ConShowOthers(IConsole::IResult *pResult, void *pUserData)
2011-01-06 05:08:12 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-08-26 18:03:30 +00:00
if(!CheckClientID(pResult->m_ClientID)) return;
2011-08-26 18:03:30 +00:00
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID];
2011-02-16 08:17:47 +00:00
if(!pPlayer)
return;
if(g_Config.m_SvShowOthers)
2011-02-23 20:22:05 +00:00
{
if(pPlayer->m_IsUsingDDRaceClient)
{
if(pResult->NumArguments())
pPlayer->m_ShowOthers = pResult->GetInteger(0);
else
pPlayer->m_ShowOthers = !pPlayer->m_ShowOthers;
}
2011-02-23 20:22:05 +00:00
else
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Showing players from other teams is only available with DDRace Client, http://DDRace.info");
2011-02-23 20:22:05 +00:00
}
2011-01-06 05:08:12 +00:00
else
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Showing players from other teams is disabled by the server admin");
2011-01-06 05:08:12 +00:00
}
void CGameContext::Mute(IConsole::IResult *pResult, NETADDR *Addr, int Secs, const char *pDisplayName)
2011-02-08 12:44:59 +00:00
{
char aBuf[128];
2011-02-23 21:39:53 +00:00
int Found = 0;
2011-02-08 12:44:59 +00:00
// find a matching mute for this ip, update expiration time if found
2011-02-23 21:39:53 +00:00
for(int i = 0; i < m_NumMutes; i++)
{
if(net_addr_comp(&m_aMutes[i].m_Addr, Addr) == 0)
{
m_aMutes[i].m_Expire = Server()->Tick() + Secs * Server()->TickSpeed();
Found = 1;
}
}
2011-02-08 12:44:59 +00:00
2011-02-23 21:39:53 +00:00
if(!Found) // nothing found so far, find a free slot..
{
if(m_NumMutes < MAX_MUTES)
{
m_aMutes[m_NumMutes].m_Addr = *Addr;
m_aMutes[m_NumMutes].m_Expire = Server()->Tick() + Secs * Server()->TickSpeed();
2011-02-25 22:13:14 +00:00
m_NumMutes++;
2011-02-23 21:39:53 +00:00
Found = 1;
}
}
if(Found)
2011-02-08 12:44:59 +00:00
{
str_format(aBuf, sizeof aBuf, "'%s' has been muted for %d seconds.", pDisplayName, Secs);
SendChat(-1, CHAT_ALL, aBuf);
}
else if(pResult)// no free slot found
// pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "mute array is full");
// Todo(Shereef Marzouk: Fix this
dbg_msg("mutes", "mute array is full");
2011-02-08 12:44:59 +00:00
}
void CGameContext::ConMute(IConsole::IResult *pResult, void *pUserData)
2011-02-08 12:44:59 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "Use either 'muteid <client_id> <seconds>' or 'muteip <ip> <seconds>'");
2011-02-08 12:44:59 +00:00
}
// mute through client id
void CGameContext::ConMuteID(IConsole::IResult *pResult, void *pUserData)
2011-02-08 12:44:59 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
int Victim = pResult->GetInteger(0);
2011-02-08 12:44:59 +00:00
2011-02-23 21:39:53 +00:00
NETADDR Addr;
pSelf->Server()->GetClientAddr(Victim, &Addr);
2011-02-08 12:44:59 +00:00
pSelf->Mute(pResult, &Addr, clamp(pResult->GetInteger(0), 1, 86400), pSelf->Server()->ClientName(Victim));
2011-02-08 12:44:59 +00:00
}
// mute through ip, arguments reversed to workaround parsing
void CGameContext::ConMuteIP(IConsole::IResult *pResult, void *pUserData)
2011-02-08 12:44:59 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-02-23 21:39:53 +00:00
NETADDR Addr;
if(net_addr_from_str(&Addr, pResult->GetString(0)))
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "Invalid network address to mute");
2011-02-23 21:39:53 +00:00
}
pSelf->Mute(pResult, &Addr, clamp(pResult->GetInteger(1), 1, 86400), pResult->GetString(0));
2011-02-08 12:44:59 +00:00
}
// unmute by mute list index
void CGameContext::ConUnmute(IConsole::IResult *pResult, void *pUserData)
2011-02-08 12:44:59 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-02-23 21:39:53 +00:00
char aIpBuf[64];
char aBuf[64];
int Victim = pResult->GetInteger(0);
2011-02-08 12:44:59 +00:00
2011-04-14 02:38:03 +00:00
if(Victim < 0 || Victim >= pSelf->m_NumMutes)
2011-02-08 12:44:59 +00:00
return;
2011-02-23 21:39:53 +00:00
pSelf->m_NumMutes--;
2011-04-14 02:38:03 +00:00
pSelf->m_aMutes[Victim] = pSelf->m_aMutes[pSelf->m_NumMutes];
2011-02-08 12:44:59 +00:00
2011-04-14 02:38:03 +00:00
net_addr_str(&pSelf->m_aMutes[Victim].m_Addr, aIpBuf, sizeof(aIpBuf));
2011-02-23 21:39:53 +00:00
str_format(aBuf, sizeof(aBuf), "Unmuted %s" , aIpBuf);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", aBuf);
2011-02-08 12:44:59 +00:00
}
// list mutes
void CGameContext::ConMutes(IConsole::IResult *pResult, void *pUserData)
2011-02-08 12:44:59 +00:00
{
CGameContext *pSelf = (CGameContext *)pUserData;
2011-02-23 21:39:53 +00:00
char aIpBuf[64];
char aBuf[128];
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", "Active mutes:");
2011-02-23 21:39:53 +00:00
for(int i = 0; i < pSelf->m_NumMutes; i++)
{
net_addr_str(&pSelf->m_aMutes[i].m_Addr, aIpBuf, sizeof(aIpBuf));
str_format(aBuf, sizeof aBuf, "%d: \"%s\", %d seconds left", i, aIpBuf, (pSelf->m_aMutes[i].m_Expire - pSelf->Server()->Tick()) / pSelf->Server()->TickSpeed());
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes", aBuf);
2011-02-23 21:39:53 +00:00
}
2011-02-08 12:44:59 +00:00
}