added remove_vote command. Closes #47

This commit is contained in:
oy 2011-03-25 11:49:35 +01:00
parent a4580d451f
commit 359b806e95
6 changed files with 126 additions and 8 deletions

View file

@ -261,7 +261,11 @@ Messages = [
NetMessage("Sv_VoteClearOptions", [
]),
NetMessage("Sv_VoteOption", [
NetMessage("Sv_VoteOptionAdd", [
NetStringStrict("m_pDescription"),
]),
NetMessage("Sv_VoteOptionRemove", [
NetStringStrict("m_pDescription"),
]),

View file

@ -100,6 +100,9 @@ void CVoting::ClearOptions()
m_pFirst = 0;
m_pLast = 0;
m_pRecycleFirst = 0;
m_pRecycleLast = 0;
}
void CVoting::OnReset()
@ -144,11 +147,23 @@ void CVoting::OnMessage(int MsgType, void *pRawMsg)
{
ClearOptions();
}
else if(MsgType == NETMSGTYPE_SV_VOTEOPTION)
else if(MsgType == NETMSGTYPE_SV_VOTEOPTIONADD)
{
CNetMsg_Sv_VoteOption *pMsg = (CNetMsg_Sv_VoteOption *)pRawMsg;
CNetMsg_Sv_VoteOptionAdd *pMsg = (CNetMsg_Sv_VoteOptionAdd *)pRawMsg;
CVoteOption *pOption = (CVoteOption *)m_Heap.Allocate(sizeof(CVoteOption));
CVoteOption *pOption;
if(m_pRecycleFirst)
{
pOption = m_pRecycleFirst;
m_pRecycleFirst = m_pRecycleFirst->m_pNext;
if(m_pRecycleFirst)
m_pRecycleFirst->m_pPrev = 0;
else
m_pRecycleLast = 0;
}
else
pOption = (CVoteOption *)m_Heap.Allocate(sizeof(CVoteOption));
pOption->m_pNext = 0;
pOption->m_pPrev = m_pLast;
if(pOption->m_pPrev)
@ -159,6 +174,37 @@ void CVoting::OnMessage(int MsgType, void *pRawMsg)
str_copy(pOption->m_aDescription, pMsg->m_pDescription, sizeof(pOption->m_aDescription));
}
else if(MsgType == NETMSGTYPE_SV_VOTEOPTIONREMOVE)
{
CNetMsg_Sv_VoteOptionRemove *pMsg = (CNetMsg_Sv_VoteOptionRemove *)pRawMsg;
for(CVoteOption *pOption = m_pFirst; pOption; pOption = pOption->m_pNext)
{
if(str_comp(pOption->m_aDescription, pMsg->m_pDescription) == 0)
{
// remove it from the list
if(m_pFirst == pOption)
m_pFirst = m_pFirst->m_pNext;
if(m_pLast == pOption)
m_pLast = m_pLast->m_pPrev;
if(pOption->m_pPrev)
pOption->m_pPrev->m_pNext = pOption->m_pNext;
if(pOption->m_pNext)
pOption->m_pNext->m_pPrev = pOption->m_pPrev;
// add it to recycle list
pOption->m_pNext = 0;
pOption->m_pPrev = m_pRecycleLast;
if(pOption->m_pPrev)
pOption->m_pPrev->m_pNext = pOption;
m_pRecycleLast = pOption;
if(!m_pRecycleFirst)
m_pRecycleLast = pOption;
break;
}
}
}
}
void CVoting::OnRender()

View file

@ -34,6 +34,9 @@ public:
CVoteOption *m_pFirst;
CVoteOption *m_pLast;
CVoteOption *m_pRecycleFirst;
CVoteOption *m_pRecycleLast;
CVoting();
virtual void OnReset();
virtual void OnConsoleInit();

View file

@ -198,6 +198,7 @@ void CGameClient::OnConsoleInit()
Console()->Register("set_team", "ii", CFGFLAG_SERVER, 0, 0, "Set team of player to team");
Console()->Register("set_team_all", "i", CFGFLAG_SERVER, 0, 0, "Set team of all players to team");
Console()->Register("add_vote", "sr", CFGFLAG_SERVER, 0, 0, "Add a voting option");
Console()->Register("remove_vote", "s", CFGFLAG_SERVER, 0, 0, "remove a voting option");
Console()->Register("clear_votes", "", CFGFLAG_SERVER, 0, 0, "Clears the voting options");
Console()->Register("vote", "r", CFGFLAG_SERVER, 0, 0, "Force a vote to yes/no");

View file

@ -804,7 +804,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
CVoteOption *pCurrent = m_pVoteOptionFirst;
while(pCurrent)
{
CNetMsg_Sv_VoteOption OptionMsg;
CNetMsg_Sv_VoteOptionAdd OptionMsg;
OptionMsg.m_pDescription = pCurrent->m_aDescription;
Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, ClientID);
pCurrent = pCurrent->m_pNext;
@ -984,7 +984,7 @@ void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
CGameContext::CVoteOption *pOption = pSelf->m_pVoteOptionFirst;
while(pOption)
{
if(str_comp_nocase(pDescription, pOption->m_aCommand) == 0)
if(str_comp_nocase(pDescription, pOption->m_aDescription) == 0)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "option '%s' already exists", pDescription);
@ -1012,8 +1012,70 @@ void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
str_format(aBuf, sizeof(aBuf), "added option '%s' '%s'", pOption->m_aDescription, pOption->m_aCommand);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
// send added option to the clients
CNetMsg_Sv_VoteOption OptionMsg;
// inform clients about added option
CNetMsg_Sv_VoteOptionAdd OptionMsg;
OptionMsg.m_pDescription = pOption->m_aDescription;
pSelf->Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, -1);
}
void CGameContext::ConRemoveVote(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
const char *pDescription = pResult->GetString(0);
// check for valid option
CGameContext::CVoteOption *pOption = pSelf->m_pVoteOptionFirst;
while(pOption)
{
if(str_comp_nocase(pDescription, pOption->m_aDescription) == 0)
break;
pOption = pOption->m_pNext;
}
if(!pOption)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "option '%s' does not exist", pDescription);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
return;
}
// TODO: improve this
// remove the option
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "removed option '%s' '%s'", pOption->m_aDescription, pOption->m_aCommand);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
CHeap *pVoteOptionHeap = new CHeap();
CVoteOption *pVoteOptionFirst = 0;
CVoteOption *pVoteOptionLast = 0;
for(CVoteOption *pSrc = pSelf->m_pVoteOptionFirst; pSrc; pSrc = pSrc->m_pNext)
{
if(pSrc == pOption)
continue;
// copy option
int Len = str_length(pSrc->m_aCommand);
CVoteOption *pDst = (CGameContext::CVoteOption *)pVoteOptionHeap->Allocate(sizeof(CGameContext::CVoteOption) + Len);
pDst->m_pNext = 0;
pDst->m_pPrev = pVoteOptionLast;
if(pDst->m_pPrev)
pDst->m_pPrev->m_pNext = pDst;
pVoteOptionLast = pDst;
if(!pVoteOptionFirst)
pVoteOptionFirst = pDst;
str_copy(pDst->m_aDescription, pSrc->m_aDescription, sizeof(pDst->m_aDescription));
mem_copy(pDst->m_aCommand, pSrc->m_aCommand, Len+1);
}
// clean up
delete pSelf->m_pVoteOptionHeap;
pSelf->m_pVoteOptionHeap = pVoteOptionHeap;
pSelf->m_pVoteOptionFirst = pVoteOptionFirst;
pSelf->m_pVoteOptionLast = pVoteOptionLast;
// inform clients about removed option
CNetMsg_Sv_VoteOptionRemove OptionMsg;
OptionMsg.m_pDescription = pOption->m_aDescription;
pSelf->Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, -1);
}
@ -1073,6 +1135,7 @@ void CGameContext::OnConsoleInit()
Console()->Register("set_team_all", "i", CFGFLAG_SERVER, ConSetTeamAll, this, "");
Console()->Register("add_vote", "sr", CFGFLAG_SERVER, ConAddVote, this, "");
Console()->Register("remove_vote", "s", CFGFLAG_SERVER, ConRemoveVote, this, "");
Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "");
Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "");

View file

@ -54,6 +54,7 @@ class CGameContext : public IGameServer
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData);
static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData);
static void ConClearVotes(IConsole::IResult *pResult, void *pUserData);
static void ConVote(IConsole::IResult *pResult, void *pUserData);
static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);