From 370b93d8e10909203a45fceaea6424253a205814 Mon Sep 17 00:00:00 2001 From: SushiTee Date: Mon, 1 Aug 2011 12:11:10 +0200 Subject: fixed a warning --- src/engine/server/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 193547cc..87122225 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1587,7 +1587,7 @@ void CServer::ConchainModCommandUpdate(IConsole::IResult *pResult, void *pUserDa { CServer *pThis = static_cast(pUserData); const IConsole::CCommandInfo *pInfo = pThis->Console()->GetCommandInfo(pResult->GetString(0), CFGFLAG_SERVER, false); - int OldAccessLevel; + int OldAccessLevel = 0; if(pInfo) OldAccessLevel = pInfo->GetAccessLevel(); pfnCallback(pResult, pCallbackUserData); -- cgit 1.4.1 From c1b23535ff4669cdd21043b885e9d7ffa2bc2381 Mon Sep 17 00:00:00 2001 From: Shereef Marzouk Date: Tue, 2 Aug 2011 12:14:11 +0200 Subject: fixed typo --- src/engine/server/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 193547cc..ca268cc7 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1137,7 +1137,7 @@ int CServer::LoadMap(const char *pMapName) str_copy(m_aCurrentMap, pMapName, sizeof(m_aCurrentMap)); //map_set(df); - // load compelate map into memory for download + // load complete map into memory for download { IOHANDLE File = Storage()->OpenFile(aBuf, IOFLAG_READ, IStorage::TYPE_ALL); m_CurrentMapSize = (int)io_length(File); -- cgit 1.4.1 From c6fd4a2cc57f8d9dec7164aff98f5a73abc9698d Mon Sep 17 00:00:00 2001 From: Shereef Marzouk Date: Thu, 11 Aug 2011 10:59:14 +0200 Subject: General whitespace and tab cleanup --- src/base/system.c | 8 +- src/engine/client/sound.cpp | 60 ++++++------ src/engine/docs/client_time.txt | 2 +- src/engine/docs/prediction.txt | 2 +- src/engine/docs/server_op.txt | 4 +- src/engine/docs/snapshots.txt | 2 +- src/engine/server/server.cpp | 2 +- src/engine/serverbrowser.h | 2 +- src/engine/shared/console.cpp | 8 +- src/engine/shared/demo.cpp | 2 +- src/engine/shared/masterserver.cpp | 2 +- src/engine/shared/network_console.cpp | 6 +- src/engine/shared/network_console_conn.cpp | 2 +- src/engine/sound.h | 4 +- src/game/client/components/chat.cpp | 2 +- src/game/client/components/hud.cpp | 2 +- src/game/client/components/menus.cpp | 2 +- src/game/client/components/menus_browser.cpp | 4 +- src/game/client/components/menus_ingame.cpp | 2 +- src/game/client/components/menus_settings.cpp | 4 +- src/game/client/components/sounds.cpp | 6 +- src/game/editor/auto_map.cpp | 50 +++++----- src/game/editor/auto_map.h | 8 +- src/game/editor/editor.cpp | 130 +++++++++++++------------- src/game/editor/editor.h | 2 +- src/game/editor/layer_tiles.cpp | 4 +- src/game/editor/popups.cpp | 4 +- src/tools/dilate.cpp | 2 +- 28 files changed, 164 insertions(+), 164 deletions(-) (limited to 'src/engine/server') diff --git a/src/base/system.c b/src/base/system.c index 466e3ca6..e451cb9a 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1119,7 +1119,7 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) sockaddr_len = sizeof(addr); s = accept(sock.ipv4sock, (struct sockaddr *)&addr, &sockaddr_len); - + if (s != -1) { sockaddr_to_netaddr((const struct sockaddr *)&addr, a); @@ -1135,7 +1135,7 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) sockaddr_len = sizeof(addr); s = accept(sock.ipv6sock, (struct sockaddr *)&addr, &sockaddr_len); - + if (s != -1) { sockaddr_to_netaddr((const struct sockaddr *)&addr, a); @@ -1186,7 +1186,7 @@ int net_tcp_send(NETSOCKET sock, const void *data, int size) bytes = send((int)sock.ipv4sock, (const char*)data, size, 0); if(sock.ipv6sock >= 0) bytes = send((int)sock.ipv6sock, (const char*)data, size, 0); - + return bytes; } @@ -1198,7 +1198,7 @@ int net_tcp_recv(NETSOCKET sock, void *data, int maxsize) bytes = recv((int)sock.ipv4sock, (char*)data, maxsize, 0); if(sock.ipv6sock >= 0) bytes = recv((int)sock.ipv6sock, (char*)data, maxsize, 0); - + return bytes; } diff --git a/src/engine/client/sound.cpp b/src/engine/client/sound.cpp index aae52e32..45404d18 100644 --- a/src/engine/client/sound.cpp +++ b/src/engine/client/sound.cpp @@ -19,7 +19,7 @@ enum NUM_SAMPLES = 512, NUM_VOICES = 64, NUM_CHANNELS = 16, - + MAX_FRAMES = 1024 }; @@ -89,9 +89,9 @@ static void Mix(short *pFinalOut, unsigned Frames) // aquire lock while we are mixing lock_wait(m_SoundLock); - + MasterVol = m_SoundVolume; - + for(unsigned i = 0; i < NUM_VOICES; i++) { if(m_aVoices[i].m_pSample) @@ -103,7 +103,7 @@ static void Mix(short *pFinalOut, unsigned Frames) int Step = v->m_pSample->m_Channels; // setup input sources short *pInL = &v->m_pSample->m_pData[v->m_Tick*Step]; short *pInR = &v->m_pSample->m_pData[v->m_Tick*Step+1]; - + unsigned End = v->m_pSample->m_NumFrames-v->m_Tick; int Rvol = v->m_pChannel->m_Vol; @@ -112,7 +112,7 @@ static void Mix(short *pFinalOut, unsigned Frames) // make sure that we don't go outside the sound data if(Frames < End) End = Frames; - + // check if we have a mono sound if(v->m_pSample->m_Channels == 1) pInR = pInL; @@ -133,7 +133,7 @@ static void Mix(short *pFinalOut, unsigned Frames) Lvol = ((Range-p)*Lvol)/Range; else Rvol = ((Range-p)*Rvol)/Range; - + // falloff Lvol = (Lvol*(Range-Dist))/Range; Rvol = (Rvol*(Range-Dist))/Range; @@ -154,7 +154,7 @@ static void Mix(short *pFinalOut, unsigned Frames) pInR += Step; v->m_Tick++; } - + // free voice if not used any more if(v->m_Tick == v->m_pSample->m_NumFrames) { @@ -165,8 +165,8 @@ static void Mix(short *pFinalOut, unsigned Frames) } } } - - + + // release the lock lock_release(m_SoundLock); @@ -201,14 +201,14 @@ int CSound::Init() m_SoundEnabled = 0; m_pGraphics = Kernel()->RequestInterface(); m_pStorage = Kernel()->RequestInterface(); - + SDL_AudioSpec Format; - + m_SoundLock = lock_create(); - + if(!g_Config.m_SndEnable) return 0; - + m_MixingRate = g_Config.m_SndRate; // Set 16-bit stereo audio at 22Khz @@ -229,7 +229,7 @@ int CSound::Init() dbg_msg("client/sound", "sound init successful"); SDL_PauseAudio(0); - + m_SoundEnabled = 1; Update(); // update the volume return 0; @@ -239,17 +239,17 @@ int CSound::Update() { // update volume int WantedVolume = g_Config.m_SndVolume; - + if(!m_pGraphics->WindowActive() && g_Config.m_SndNonactiveMute) WantedVolume = 0; - + if(WantedVolume != m_SoundVolume) { lock_wait(m_SoundLock); m_SoundVolume = WantedVolume; lock_release(m_SoundLock); } - + return 0; } @@ -277,7 +277,7 @@ void CSound::RateConvert(int SampleID) CSample *pSample = &m_aSamples[SampleID]; int NumFrames = 0; short *pNewData = 0; - + // make sure that we need to convert this sound if(!pSample->m_pData || pSample->m_Rate == m_MixingRate) return; @@ -285,7 +285,7 @@ void CSound::RateConvert(int SampleID) // allocate new data NumFrames = (int)((pSample->m_NumFrames/(float)pSample->m_Rate)*m_MixingRate); pNewData = (short *)mem_alloc(NumFrames*pSample->m_Channels*sizeof(short), 1); - + for(int i = 0; i < NumFrames; i++) { // resample TODO: this should be done better, like linear atleast @@ -293,7 +293,7 @@ void CSound::RateConvert(int SampleID) int f = (int)(a*pSample->m_NumFrames); if(f >= pSample->m_NumFrames) f = pSample->m_NumFrames-1; - + // set new data if(pSample->m_Channels == 1) pNewData[i] = pSample->m_pData[f]; @@ -303,7 +303,7 @@ void CSound::RateConvert(int SampleID) pNewData[i*2+1] = pSample->m_pData[f*2+1]; } } - + // free old data and apply new mem_free(pSample->m_pData); pSample->m_pData = pNewData; @@ -321,15 +321,15 @@ int CSound::LoadWV(const char *pFilename) int SampleID = -1; char aError[100]; WavpackContext *pContext; - + // don't waste memory on sound when we are stress testing if(g_Config.m_DbgStress) return -1; - + // no need to load sound when we are running with no sound if(!m_SoundEnabled) return 1; - + if(!m_pStorage) return -1; @@ -372,7 +372,7 @@ int CSound::LoadWV(const char *pFilename) dbg_msg("sound/wv", "file is %d Hz, not 44100 Hz. filename='%s'", snd->rate, filename); return -1; }*/ - + if(BitsPerSample != 16) { dbg_msg("sound/wv", "bps is %d, not 16, filname='%s'", BitsPerSample, pFilename); @@ -382,7 +382,7 @@ int CSound::LoadWV(const char *pFilename) pData = (int *)mem_alloc(4*m_aSamples*m_aChannels, 1); WavpackUnpackSamples(pContext, pData, m_aSamples); // TODO: check return value pSrc = pData; - + pSample->m_pData = (short *)mem_alloc(2*m_aSamples*m_aChannels, 1); pDst = pSample->m_pData; @@ -428,9 +428,9 @@ int CSound::Play(int ChannelID, int SampleID, int Flags, float x, float y) { int VoiceID = -1; int i; - + lock_wait(m_SoundLock); - + // search for voice for(i = 0; i < NUM_VOICES; i++) { @@ -442,7 +442,7 @@ int CSound::Play(int ChannelID, int SampleID, int Flags, float x, float y) break; } } - + // voice found, use it if(VoiceID != -1) { @@ -457,7 +457,7 @@ int CSound::Play(int ChannelID, int SampleID, int Flags, float x, float y) m_aVoices[VoiceID].m_X = (int)x; m_aVoices[VoiceID].m_Y = (int)y; } - + lock_release(m_SoundLock); return VoiceID; } diff --git a/src/engine/docs/client_time.txt b/src/engine/docs/client_time.txt index bc76f91c..0d4dd53e 100644 --- a/src/engine/docs/client_time.txt +++ b/src/engine/docs/client_time.txt @@ -6,6 +6,6 @@ predtick, predintratick prevtick tick predtick 4 8 14 |---------------------|---------------------| - 0 <- intratick -> 1 + 0 <- intratick -> 1 0 <- ticktime(in s)-> X 0 <- predintratick?-> 1 diff --git a/src/engine/docs/prediction.txt b/src/engine/docs/prediction.txt index d5771d1a..e740b1e8 100644 --- a/src/engine/docs/prediction.txt +++ b/src/engine/docs/prediction.txt @@ -8,7 +8,7 @@ Predicted input sent to the server can be retrived by calling > { > int tick; > prediction_reset(); -> +> > for(tick = client_tick()+1; tick <= client_predtick(); tick++) > { > MY_INPUT *input = (MY_INPUT *)client_get_input(); diff --git a/src/engine/docs/server_op.txt b/src/engine/docs/server_op.txt index 59181e62..c0a054c4 100644 --- a/src/engine/docs/server_op.txt +++ b/src/engine/docs/server_op.txt @@ -25,13 +25,13 @@ while running send snapshot end for end - + process new network messages end while unload map (end) - + Section: Reinit diff --git a/src/engine/docs/snapshots.txt b/src/engine/docs/snapshots.txt index 647b049a..adb84863 100644 --- a/src/engine/docs/snapshots.txt +++ b/src/engine/docs/snapshots.txt @@ -48,7 +48,7 @@ After a snapshot have been created, compression is applyed to reduce the bandwid Topic: Interval -The interval for how often a client recives a snapshot changes during the course of the connection. There are three different snapshot rates. +The interval for how often a client recives a snapshot changes during the course of the connection. There are three different snapshot rates. - *Init*. 5 snapshots per second. Used when a client is connecting and used until the client has acknowlaged a snapshot. This mechanism is used because the first snapshot because no delta compression can be done. diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 6f6d9e1c..93e96db9 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -672,7 +672,7 @@ void CServer::SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int Cli void CServer::UpdateClientRconCommands() { int ClientID = Tick() % MAX_CLIENTS; - + if(m_aClients[ClientID].m_State != CClient::STATE_EMPTY && m_aClients[ClientID].m_Authed) { int ConsoleAccessLevel = m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD; diff --git a/src/engine/serverbrowser.h b/src/engine/serverbrowser.h index 1a49eaf0..79919b09 100644 --- a/src/engine/serverbrowser.h +++ b/src/engine/serverbrowser.h @@ -24,7 +24,7 @@ public: int m_Country; int m_Score; bool m_Player; - + int m_FriendState; }; diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index e4cb1991..de5116c1 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -665,7 +665,7 @@ void CConsole::Register(const char *pName, const char *pParams, pCommand->m_pName = pName; pCommand->m_pHelp = pHelp; pCommand->m_pParams = pParams; - + pCommand->m_Flags = Flags; pCommand->m_Temp = false; @@ -699,7 +699,7 @@ void CConsole::RegisterTemp(const char *pName, const char *pParams, int Flags, c } pCommand->m_pfnCallback = 0; - pCommand->m_pUserData = 0; + pCommand->m_pUserData = 0; pCommand->m_Flags = Flags; pCommand->m_Temp = true; @@ -729,7 +729,7 @@ void CConsole::DeregisterTemp(const char *pName) break; } } - + // add to recycle list if(pRemoved) { @@ -742,7 +742,7 @@ void CConsole::DeregisterTempAll() { // set non temp as first one for(; m_pFirstCommand && m_pFirstCommand->m_Temp; m_pFirstCommand = m_pFirstCommand->m_pNext); - + // remove temp entries from command list for(CCommand *pCommand = m_pFirstCommand; pCommand && pCommand->m_pNext; pCommand = pCommand->m_pNext) { diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index 51dd51d9..2bd7c28a 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -775,7 +775,7 @@ void CDemoPlayer::GetDemoName(char *pBuffer, int BufferSize) const else if(*pFileName == '.') pEnd = pFileName; } - + int Length = pEnd > pExtractedName ? min(BufferSize, (int)(pEnd-pExtractedName+1)) : BufferSize; str_copy(pBuffer, pExtractedName, Length); } diff --git a/src/engine/shared/masterserver.cpp b/src/engine/shared/masterserver.cpp index 1271eeaf..eb63bab5 100644 --- a/src/engine/shared/masterserver.cpp +++ b/src/engine/shared/masterserver.cpp @@ -157,7 +157,7 @@ public: Added = true; break; } - + if(!Added) { for(int i = 0; i < MAX_MASTERSERVERS; ++i) diff --git a/src/engine/shared/network_console.cpp b/src/engine/shared/network_console.cpp index 13ed3751..cfa081a2 100644 --- a/src/engine/shared/network_console.cpp +++ b/src/engine/shared/network_console.cpp @@ -56,7 +56,7 @@ int CNetConsole::AcceptClient(NETSOCKET Socket, const NETADDR *pAddr) { char aError[256] = { 0 }; int FreeSlot = -1; - + // look for free slot or multiple client for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) { @@ -115,7 +115,7 @@ int CNetConsole::Update() } else str_format(aBuf, sizeof(aBuf), "You have been banned for life"); - + net_tcp_send(Socket, aBuf, str_length(aBuf)); net_tcp_close(Socket); } @@ -170,7 +170,7 @@ bool CNetConsole::AddBan(NETADDR Addr, int Seconds) { if(m_NumBans == MAX_BANS) return false; - + Addr.port = 0; int Index = FindBan(Addr); if(Index == -1) diff --git a/src/engine/shared/network_console_conn.cpp b/src/engine/shared/network_console_conn.cpp index 75b581fa..9bc163af 100644 --- a/src/engine/shared/network_console_conn.cpp +++ b/src/engine/shared/network_console_conn.cpp @@ -181,6 +181,6 @@ int CConsoleNetConnection::Send(const char *pLine) pData += Send; Length -= Send; } - + return 0; } diff --git a/src/engine/sound.h b/src/engine/sound.h index f55a978d..fa5bfc85 100644 --- a/src/engine/sound.h +++ b/src/engine/sound.h @@ -19,10 +19,10 @@ public: virtual bool IsSoundEnabled() = 0; virtual int LoadWV(const char *pFilename) = 0; - + virtual void SetChannel(int ChannelID, float Volume, float Panning) = 0; virtual void SetListenerPos(float x, float y) = 0; - + virtual int PlayAt(int ChannelID, int SampleID, int Flags, float x, float y) = 0; virtual int Play(int ChannelID, int SampleID, int Flags) = 0; virtual void Stop(int SampleID) = 0; diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index aba38bf6..a3bf5252 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -283,7 +283,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) m_aLines[m_CurrentLine].m_ClientID = ClientID; m_aLines[m_CurrentLine].m_Team = Team; m_aLines[m_CurrentLine].m_NameColor = -2; - + // check for highlighted name const char *pHL = str_find_nocase(pLine, m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_aName); if(pHL) diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 11343912..17365116 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -108,7 +108,7 @@ void CHud::RenderScoreHud() if(GameFlags&GAMEFLAG_FLAGS) { - int BlinkTimer = (m_pClient->m_FlagDropTick[t] != 0 && + int BlinkTimer = (m_pClient->m_FlagDropTick[t] != 0 && (Client()->GameTick()-m_pClient->m_FlagDropTick[t])/Client()->GameTickSpeed() >= 25) ? 10 : 20; if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick()/BlinkTimer)&1))) { diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 8f330f78..8813c667 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1108,7 +1108,7 @@ int CMenus::Render() Box.HSplitBottom(24.f, &Box, &Part); Box.HSplitBottom(20.f, &Box, 0); Box.VMargin(20.0f, &Box); - + static int ActSelection = -2; if(ActSelection == -2) ActSelection = g_Config.m_BrFilterCountryIndex; diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 8501c67d..825fe3da 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -516,7 +516,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); if (DoButton_CheckBox((char *)&g_Config.m_BrFilterPureMap, Localize("Standard map"), g_Config.m_BrFilterPureMap, &Button)) g_Config.m_BrFilterPureMap ^= 1; - + ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); if (DoButton_CheckBox((char *)&g_Config.m_BrFilterGametypeStrict, Localize("Strict gametype filter"), g_Config.m_BrFilterGametypeStrict, &Button)) g_Config.m_BrFilterGametypeStrict ^= 1; @@ -563,7 +563,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) Button.HMargin(3.0f, &Button); if(DoButton_CheckBox(&g_Config.m_BrFilterCountry, Localize("Player country:"), g_Config.m_BrFilterCountry, &Button)) g_Config.m_BrFilterCountry ^= 1; - + float OldWidth = Rect.w; Rect.w = Rect.h*2; Rect.x += (OldWidth-Rect.w)/2.0f; diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index a809aef0..1afcefe5 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -391,7 +391,7 @@ void CMenus::RenderServerControlKick(CUIRect MainView, bool FilterSpectators) { if(!m_pClient->m_Snap.m_paInfoByTeam[i]) continue; - + int Index = m_pClient->m_Snap.m_paInfoByTeam[i]->m_ClientID; if(Index == m_pClient->m_Snap.m_LocalClientID || FilterSpectators && m_pClient->m_Snap.m_paInfoByTeam[i]->m_Team == TEAM_SPECTATORS) continue; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 51fdbd29..7692ac27 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -543,7 +543,7 @@ void CMenus::RenderSettingsControls(CUIRect MainView) WeaponSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &WeaponSettings); UiDoGetButtons(5, 12, WeaponSettings); } - + // defaults { ResetButton.HSplitTop(10.0f, 0, &ResetButton); @@ -554,7 +554,7 @@ void CMenus::RenderSettingsControls(CUIRect MainView) if(DoButton_Menu((void*)&s_DefaultButton, Localize("Reset to defaults"), 0, &ResetButton)) m_pClient->m_pBinds->SetDefaults(); } - + // voting settings { VotingSettings.VSplitLeft(10.0f, 0, &VotingSettings); diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp index c4ade00e..65fb56fb 100644 --- a/src/game/client/components/sounds.cpp +++ b/src/game/client/components/sounds.cpp @@ -144,7 +144,7 @@ void CSounds::Play(int Chn, int SetId, float Vol, vec2 Pos) if(!pSet->m_NumSounds) return; - + int Flags = 0; if(Chn == CHN_MUSIC) Flags = ISound::FLAG_LOOP; @@ -170,9 +170,9 @@ void CSounds::Stop(int SetId) { if(m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds) return; - + CDataSoundset *pSet = &g_pData->m_aSounds[SetId]; - + for(int i = 0; i < pSet->m_NumSounds; i++) Sound()->Stop(pSet->m_aSounds[i].m_Id); } diff --git a/src/game/editor/auto_map.cpp b/src/game/editor/auto_map.cpp index 528e459b..3abcf0f4 100644 --- a/src/game/editor/auto_map.cpp +++ b/src/game/editor/auto_map.cpp @@ -20,15 +20,15 @@ void CAutoMapper::Load(const char* pTileName) IOHANDLE RulesFile = m_pEditor->Storage()->OpenFile(aPath, IOFLAG_READ, IStorage::TYPE_ALL); if(!RulesFile) return; - + CLineReader LineReader; LineReader.Init(RulesFile); - + CConfiguration *pCurrentConf = 0; CIndexRule *pCurrentIndex = 0; - + char aBuf[256]; - + // read each line while(char *pLine = LineReader.Get()) { @@ -40,11 +40,11 @@ void CAutoMapper::Load(const char* pTileName) { // new configuration, get the name pLine++; - + CConfiguration NewConf; int ID = m_lConfigs.add(NewConf); pCurrentConf = &m_lConfigs[ID]; - + str_copy(pCurrentConf->m_aName, pLine, str_length(pLine)); } else @@ -54,15 +54,15 @@ void CAutoMapper::Load(const char* pTileName) // new index int ID = 0; char aFlip[128] = ""; - + sscanf(pLine, "Index %d %127s", &ID, aFlip); - + CIndexRule NewIndexRule; NewIndexRule.m_ID = ID; NewIndexRule.m_Flag = 0; NewIndexRule.m_RandomValue = 0; NewIndexRule.m_BaseTile = false; - + if(str_length(aFlip) > 0) { if(!str_comp(aFlip, "XFLIP")) @@ -70,7 +70,7 @@ void CAutoMapper::Load(const char* pTileName) else if(!str_comp(aFlip, "YFLIP")) NewIndexRule.m_Flag = TILEFLAG_HFLIP; } - + // add the index rule object and make it current int ArrayID = pCurrentConf->m_aIndexRules.add(NewIndexRule); pCurrentIndex = &pCurrentConf->m_aIndexRules[ArrayID]; @@ -85,9 +85,9 @@ void CAutoMapper::Load(const char* pTileName) char aValue[128]; int Value = CPosRule::EMPTY; bool IndexValue = false; - + sscanf(pLine, "Pos %d %d %127s", &x, &y, aValue); - + if(!str_comp(aValue, "FULL")) Value = CPosRule::FULL; else if(!str_comp_num(aValue, "INDEX", 5)) @@ -106,12 +106,12 @@ void CAutoMapper::Load(const char* pTileName) } } } - + io_close(RulesFile); - + str_format(aBuf, sizeof(aBuf),"loaded %s", aPath); m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "editor", aBuf); - + m_FileLoaded = true; } @@ -127,14 +127,14 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID) { if(!m_FileLoaded || pLayer->m_Readonly || ConfigID < 0 || ConfigID >= m_lConfigs.size()) return; - + CConfiguration *pConf = &m_lConfigs[ConfigID]; - + if(!pConf->m_aIndexRules.size()) return; - + int BaseTile = 1; - + // find base tile if there is one for(int i = 0; i < pConf->m_aIndexRules.size(); ++i) { @@ -144,7 +144,7 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID) break; } } - + // auto map ! int MaxIndex = pLayer->m_Width*pLayer->m_Height; for(int y = 0; y < pLayer->m_Height; y++) @@ -159,7 +159,7 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID) if(y == 0 || y == pLayer->m_Height-1 || x == 0 || x == pLayer->m_Width-1) continue; - + for(int i = 0; i < pConf->m_aIndexRules.size(); ++i) { if(pConf->m_aIndexRules[i].m_BaseTile) @@ -170,7 +170,7 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID) { CPosRule *pRule = &pConf->m_aIndexRules[i].m_aRules[j]; int CheckIndex = (y+pRule->m_Y)*pLayer->m_Width+(x+pRule->m_X); - + if(CheckIndex < 0 || CheckIndex >= MaxIndex) RespectRules = false; else @@ -184,15 +184,15 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID) { if(pLayer->m_pTiles[CheckIndex].m_Index > 0 && pRule->m_Value == CPosRule::EMPTY) RespectRules = false; - + if(pLayer->m_pTiles[CheckIndex].m_Index == 0 && pRule->m_Value == CPosRule::FULL) RespectRules = false; } } } - + if(RespectRules && - (pConf->m_aIndexRules[i].m_RandomValue <= 1 || (int)((float)rand() / ((float)RAND_MAX + 1) * pConf->m_aIndexRules[i].m_RandomValue) == 1)) + (pConf->m_aIndexRules[i].m_RandomValue <= 1 || (int)((float)rand() / ((float)RAND_MAX + 1) * pConf->m_aIndexRules[i].m_RandomValue) == 1)) { pTile->m_Index = pConf->m_aIndexRules[i].m_ID; pTile->m_Flags = pConf->m_aIndexRules[i].m_Flag; diff --git a/src/game/editor/auto_map.h b/src/game/editor/auto_map.h index ee570378..c5537d4f 100644 --- a/src/game/editor/auto_map.h +++ b/src/game/editor/auto_map.h @@ -11,7 +11,7 @@ class CAutoMapper int m_Y; int m_Value; bool m_IndexValue; - + enum { EMPTY=0, @@ -33,16 +33,16 @@ class CAutoMapper array m_aIndexRules; char m_aName[128]; }; - + public: CAutoMapper(class CEditor *pEditor); - + void Load(const char* pTileName); void Proceed(class CLayerTiles *pLayer, int ConfigID); int ConfigNamesNum() { return m_lConfigs.size(); } const char* GetConfigName(int Index); - + const bool IsLoaded() { return m_FileLoaded; } private: array m_lConfigs; diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 84308ab6..b7c1d0cb 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -164,7 +164,7 @@ void CEditorImage::AnalyseTileFlags() int tw = m_Width/16; // tilesizes int th = m_Height/16; if ( tw == th ) - { + { unsigned char *pPixelData = (unsigned char *)m_pData; int TileID = 0; @@ -381,8 +381,8 @@ float CEditor::UiDoScrollbarV(const void *pID, const CUIRect *pRect, float Curre Handle.y += (pRect->h-Handle.h)*Current; // logic - float Ret = Current; - int Inside = UI()->MouseInside(&Handle); + float Ret = Current; + int Inside = UI()->MouseInside(&Handle); if(UI()->ActiveItem() == pID) { @@ -423,7 +423,7 @@ float CEditor::UiDoScrollbarV(const void *pID, const CUIRect *pRect, float Curre Slider.Margin(5.0f, &Slider); RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f); - return Ret; + return Ret; } vec4 CEditor::GetButtonColor(const void *pID, int Checked) @@ -490,7 +490,7 @@ int CEditor::DoButton_File(const void *pID, const char *pText, int Checked, cons int CEditor::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip) { CUIRect r = *pRect; - RenderTools()->DrawUIRect(&r, vec4(0.5f, 0.5f, 0.5f, 1.0f), CUI::CORNER_T, 3.0f); + RenderTools()->DrawUIRect(&r, vec4(0.5f, 0.5f, 0.5f, 1.0f), CUI::CORNER_T, 3.0f); r = *pRect; r.VMargin(5.0f, &r); @@ -515,18 +515,18 @@ int CEditor::DoButton_MenuItem(const void *pID, const char *pText, int Checked, int CEditor::DoButton_Tab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip) { RenderTools()->DrawUIRect(pRect, GetButtonColor(pID, Checked), CUI::CORNER_T, 5.0f); - CUIRect NewRect = *pRect; - NewRect.y += NewRect.h/2.0f-7.0f; - UI()->DoLabel(&NewRect, pText, 10, 0, -1); + CUIRect NewRect = *pRect; + NewRect.y += NewRect.h/2.0f-7.0f; + UI()->DoLabel(&NewRect, pText, 10, 0, -1); return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip); } int CEditor::DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize) { RenderTools()->DrawUIRect(pRect, GetButtonColor(pID, Checked), Corners, 3.0f); - CUIRect NewRect = *pRect; - NewRect.HMargin(NewRect.h/2.0f-FontSize/2.0f-1.0f, &NewRect); - UI()->DoLabel(&NewRect, pText, FontSize, 0, -1); + CUIRect NewRect = *pRect; + NewRect.HMargin(NewRect.h/2.0f-FontSize/2.0f-1.0f, &NewRect); + UI()->DoLabel(&NewRect, pText, FontSize, 0, -1); return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip); } @@ -550,7 +550,7 @@ void CEditor::RenderGrid(CLayerGroup *pGroup) return; float aGroupPoints[4]; - pGroup->Mapping(aGroupPoints); + pGroup->Mapping(aGroupPoints); float w = UI()->Screen()->w; float h = UI()->Screen()->h; @@ -562,7 +562,7 @@ void CEditor::RenderGrid(CLayerGroup *pGroup) int XGridOffset = XOffset % m_GridFactor; int YGridOffset = YOffset % m_GridFactor; - Graphics()->TextureSet(-1); + Graphics()->TextureSet(-1); Graphics()->LinesBegin(); for(int i = 0; i < (int)w; i++) @@ -601,9 +601,9 @@ void CEditor::RenderBackground(CUIRect View, int Texture, float Size, float Brig int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, int Current, int Min, int Max, int Step, float Scale, const char *pToolTip) { - // logic - static float s_Value; - int Inside = UI()->MouseInside(pRect); + // logic + static float s_Value; + int Inside = UI()->MouseInside(pRect); if(UI()->ActiveItem() == pID) { @@ -652,9 +652,9 @@ int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, in char aBuf[128]; str_format(aBuf, sizeof(aBuf),"%s %d", pLabel, Current); RenderTools()->DrawUIRect(pRect, GetButtonColor(pID, 0), CUI::CORNER_ALL, 5.0f); - pRect->y += pRect->h/2.0f-7.0f; - UI()->DoLabel(pRect, aBuf, 10, 0, -1); - + pRect->y += pRect->h/2.0f-7.0f; + UI()->DoLabel(pRect, aBuf, 10, 0, -1); + return Current; } @@ -713,7 +713,7 @@ void CEditor::CallbackAppendMap(const char *pFileName, int StorageType, void *pU pEditor->m_aFileName[0] = 0; else pEditor->SortImages(); - + pEditor->m_Dialog = DIALOG_NONE; } void CEditor::CallbackSaveMap(const char *pFileName, int StorageType, void *pUser) @@ -734,7 +734,7 @@ void CEditor::CallbackSaveMap(const char *pFileName, int StorageType, void *pUse pEditor->m_ValidSaveFilename = StorageType == IStorage::TYPE_SAVE && pEditor->m_pFileDialogPath == pEditor->m_aFileDialogCurrentFolder; pEditor->m_Map.m_Modified = false; } - + pEditor->m_Dialog = DIALOG_NONE; } @@ -742,11 +742,11 @@ void CEditor::DoToolbar(CUIRect ToolBar) { CUIRect TB_Top, TB_Bottom; CUIRect Button; - + ToolBar.HSplitTop(ToolBar.h/2.0f, &TB_Top, &TB_Bottom); - - TB_Top.HSplitBottom(2.5f, &TB_Top, 0); - TB_Bottom.HSplitTop(2.5f, 0, &TB_Bottom); + + TB_Top.HSplitBottom(2.5f, &TB_Top, 0); + TB_Bottom.HSplitTop(2.5f, 0, &TB_Bottom); // ctrl+o to open if(Input()->KeyDown('o') && (Input()->KeyPressed(KEY_LCTRL) || Input()->KeyPressed(KEY_RCTRL))) @@ -763,7 +763,7 @@ void CEditor::DoToolbar(CUIRect ToolBar) // ctrl+s to save if(Input()->KeyDown('s') && (Input()->KeyPressed(KEY_LCTRL) || Input()->KeyPressed(KEY_RCTRL))) { - if(m_aFileName[0] && m_ValidSaveFilename) + if(m_aFileName[0] && m_ValidSaveFilename) { str_copy(m_aFileSaveName, m_aFileName, sizeof(m_aFileSaveName)); m_PopupEventType = POPEVENT_SAVE; @@ -947,13 +947,13 @@ void CEditor::DoToolbar(CUIRect ToolBar) } } } - + // tile manipulation { TB_Bottom.VSplitLeft(40.0f, &Button, &TB_Bottom); static int s_BorderBut = 0; CLayerTiles *pT = (CLayerTiles *)GetSelectedLayerType(0, LAYERTYPE_TILES); - + if(DoButton_Editor(&s_BorderBut, "Border", pT?0:-1, &Button, 0, "Adds border tiles")) { if(pT) @@ -1102,14 +1102,14 @@ void CEditor::DoQuad(CQuad *q, int Index) y = (int)((wy+(LineDistance/2)*m_GridFactor)/(LineDistance*m_GridFactor)) * (LineDistance*m_GridFactor); else y = (int)((wy-(LineDistance/2)*m_GridFactor)/(LineDistance*m_GridFactor)) * (LineDistance*m_GridFactor); - + int OldX = q->m_aPoints[4].x; int OldY = q->m_aPoints[4].y; q->m_aPoints[4].x = f2fx(x); q->m_aPoints[4].y = f2fx(y); int DiffX = q->m_aPoints[4].x - OldX; int DiffY = q->m_aPoints[4].y - OldY; - + for(int v = 0; v < 4; v++) { q->m_aPoints[v].x += DiffX; @@ -1198,7 +1198,7 @@ void CEditor::DoQuad(CQuad *q, int Index) { if(m_SelectedQuad != Index) m_SelectedPoints = 0; - m_SelectedQuad = Index; + m_SelectedQuad = Index; s_Operation = OP_CONTEXT_MENU; UI()->SetActiveItem(pID); } @@ -1295,12 +1295,12 @@ void CEditor::DoQuadPoint(CQuad *pQuad, int QuadIndex, int V) for(int m = 0; m < 4; m++) if(m_SelectedPoints&(1<m_aTexcoords[m].x += f2fx(dx*0.001f); pQuad->m_aTexcoords[(m+2)%4].x += f2fx(dx*0.001f); - + pQuad->m_aTexcoords[m].y += f2fx(dy*0.001f); pQuad->m_aTexcoords[m^1].y += f2fx(dy*0.001f); } @@ -1590,8 +1590,8 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) { if(!UI()->MouseButton(0)) { - for(int k = 0; k < NumEditLayers; k++) - pEditLayers[k]->FillSelection(m_Brush.IsEmpty(), m_Brush.m_lLayers[0], r); + for(int k = 0; k < NumEditLayers; k++) + pEditLayers[k]->FillSelection(m_Brush.IsEmpty(), m_Brush.m_lLayers[0], r); } else { @@ -1623,10 +1623,10 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) } } - + CLayerTiles *pLayer = (CLayerTiles*)GetSelectedLayerType(0, LAYERTYPE_TILES); if((Input()->KeyPressed(KEY_LSHIFT) || Input()->KeyPressed(KEY_RSHIFT)) && pLayer) - s_Operation = OP_BRUSH_PAINT; + s_Operation = OP_BRUSH_PAINT; } if(!m_Brush.IsEmpty()) @@ -1736,7 +1736,7 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) { CLayerGroup *g = m_Map.m_pGameGroup; g->MapScreen(); - + Graphics()->TextureSet(-1); Graphics()->LinesBegin(); @@ -1935,7 +1935,7 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * if(pProps[i].m_Value < 0) str_copy(aBuf, "None", sizeof(aBuf)); else - str_format(aBuf, sizeof(aBuf),"%s", m_Map.m_lImages[pProps[i].m_Value]->m_aName); + str_format(aBuf, sizeof(aBuf),"%s", m_Map.m_lImages[pProps[i].m_Value]->m_aName); if(DoButton_Editor(&pIDs[i], aBuf, 0, &Shifter, 0, 0)) PopupSelectImageInvoke(pProps[i].m_Value, UI()->MouseX(), UI()->MouseY()); @@ -2174,8 +2174,8 @@ void CEditor::ReplaceImage(const char *pFileName, int StorageType, void *pUser) pEditor->SortImages(); for(int i = 0; i < pEditor->m_Map.m_lImages.size(); ++i) { - if(!str_comp(pEditor->m_Map.m_lImages[i]->m_aName, pImg->m_aName)) - pEditor->m_SelectedImage = i; + if(!str_comp(pEditor->m_Map.m_lImages[i]->m_aName, pImg->m_aName)) + pEditor->m_SelectedImage = i; } pEditor->m_Dialog = DIALOG_NONE; } @@ -2192,8 +2192,8 @@ void CEditor::AddImage(const char *pFileName, int StorageType, void *pUser) ExtractName(pFileName, aBuf, sizeof(aBuf)); for(int i = 0; i < pEditor->m_Map.m_lImages.size(); ++i) { - if(!str_comp(pEditor->m_Map.m_lImages[i]->m_aName, aBuf)) - return; + if(!str_comp(pEditor->m_Map.m_lImages[i]->m_aName, aBuf)) + return; } CEditorImage *pImg = new CEditorImage(pEditor); @@ -2319,7 +2319,7 @@ void CEditor::SortImages() gs_pSortedIndex = 0; } } - + void CEditor::RenderImages(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) { @@ -2750,7 +2750,7 @@ void CEditor::InvokeFileDialog(int StorageType, int FileType, const char *pTitle str_copy(m_aFileDialogFileName, pDefaultName, sizeof(m_aFileDialogFileName)); if(pBasePath) str_copy(m_aFileDialogCurrentFolder, pBasePath, sizeof(m_aFileDialogCurrentFolder)); - + FilelistPopulate(m_FileDialogStorageType); m_Dialog = DIALOG_FILE; @@ -2770,10 +2770,10 @@ void CEditor::RenderModebar(CUIRect View) const char *pButName = m_Mode == MODE_LAYERS ? "Layers" : "Images"; if(DoButton_Tab(&s_Button, pButName, 0, &Button, 0, "Switch between images and layers managment.")) { - if(m_Mode == MODE_LAYERS) - m_Mode = MODE_IMAGES; - else - m_Mode = MODE_LAYERS; + if(m_Mode == MODE_LAYERS) + m_Mode = MODE_IMAGES; + else + m_Mode = MODE_LAYERS; } } @@ -3127,7 +3127,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) UI()->SetActiveItem(0); } else - { + { if(Input()->KeyPressed(KEY_LSHIFT) || Input()->KeyPressed(KEY_RSHIFT)) { if(i != 0) @@ -3482,12 +3482,12 @@ void CEditor::Reset(bool CreateDefault) m_SelectedPoints = 0; m_SelectedEnvelope = 0; m_SelectedImage = 0; - + m_WorldOffsetX = 0; m_WorldOffsetY = 0; m_EditorOffsetX = 0.0f; m_EditorOffsetY = 0.0f; - + m_WorldZoom = 1.0f; m_ZoomLevel = 200; @@ -3633,19 +3633,19 @@ void CEditor::Init() void CEditor::DoMapBorder() { - CLayerTiles *pT = (CLayerTiles *)GetSelectedLayerType(0, LAYERTYPE_TILES); - - for(int i = 0; i < pT->m_Width*2; ++i) - pT->m_pTiles[i].m_Index = 1; - - for(int i = 0; i < pT->m_Width*pT->m_Height; ++i) - { - if(i%pT->m_Width < 2 || i%pT->m_Width > pT->m_Width-3) - pT->m_pTiles[i].m_Index = 1; - } - - for(int i = (pT->m_Width*(pT->m_Height-2)); i < pT->m_Width*pT->m_Height; ++i) - pT->m_pTiles[i].m_Index = 1; + CLayerTiles *pT = (CLayerTiles *)GetSelectedLayerType(0, LAYERTYPE_TILES); + + for(int i = 0; i < pT->m_Width*2; ++i) + pT->m_pTiles[i].m_Index = 1; + + for(int i = 0; i < pT->m_Width*pT->m_Height; ++i) + { + if(i%pT->m_Width < 2 || i%pT->m_Width > pT->m_Width-3) + pT->m_pTiles[i].m_Index = 1; + } + + for(int i = (pT->m_Width*(pT->m_Height-2)); i < pT->m_Width*pT->m_Height; ++i) + pT->m_pTiles[i].m_Index = 1; } void CEditor::UpdateAndRender() diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 1a904953..db99a78c 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -713,7 +713,7 @@ public: void PopupSelectGametileOpInvoke(float x, float y); int PopupSelectGameTileOpResult(); - + void PopupSelectConfigAutoMapInvoke(float x, float y); int PopupSelectConfigAutoMapResult(); diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index eb78a23d..7532c1bd 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -363,7 +363,7 @@ void CLayerTiles::ShowInfo() int CLayerTiles::RenderProperties(CUIRect *pToolBox) { CUIRect Button; - + bool InGameGroup = !find_linear(m_pEditor->m_Map.m_pGameGroup->m_lLayers.all(), this).empty(); if(m_pEditor->m_Map.m_pGameLayer != this) { @@ -373,7 +373,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) pToolBox->HSplitBottom(12.0f, pToolBox, &Button); if(m_pEditor->DoButton_Editor(&s_AutoMapperButton, "Auto map", 0, &Button, 0, "")) m_pEditor->PopupSelectConfigAutoMapInvoke(m_pEditor->UI()->MouseX(), m_pEditor->UI()->MouseY()); - + int Result = m_pEditor->PopupSelectConfigAutoMapResult(); if(Result > -1) { diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 0d8036e3..a97146aa 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -811,7 +811,7 @@ int CEditor::PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View) CUIRect Button; static int s_AutoMapperConfigButtons[256]; CAutoMapper *pAutoMapper = &pEditor->m_Map.m_lImages[pLayer->m_Image]->m_AutoMapper; - + for(int i = 0; i < pAutoMapper->ConfigNamesNum(); ++i) { View.HSplitTop(2.0f, 0, &View); @@ -837,7 +837,7 @@ int CEditor::PopupSelectConfigAutoMapResult() { if(s_AutoMapConfigSelected < 0) return -1; - + int Result = s_AutoMapConfigSelected; s_AutoMapConfigSelected = -1; return Result; diff --git a/src/tools/dilate.cpp b/src/tools/dilate.cpp index eb770a90..55094a5b 100644 --- a/src/tools/dilate.cpp +++ b/src/tools/dilate.cpp @@ -96,7 +96,7 @@ int main(int argc, const char **argv) dbg_msg("Usage", "%s FILE1 [ FILE2... ]", argv[0]); return -1; } - + for(int i = 1; i < argc; i++) DilateFile(argv[i]); return 0; -- cgit 1.4.1 From b2a825652d8588dfb7f1c793403ca05555b1d75f Mon Sep 17 00:00:00 2001 From: Choupom Date: Tue, 6 Sep 2011 16:49:55 +0200 Subject: added a command to unban all --- src/engine/server/server.cpp | 13 +++++++++++++ src/engine/server/server.h | 2 ++ src/engine/shared/network.h | 1 + src/engine/shared/network_server.cpp | 33 +++++++++++++++++++++++---------- 4 files changed, 39 insertions(+), 10 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 93e96db9..d253d3fc 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1061,6 +1061,11 @@ int CServer::BanRemove(NETADDR Addr) return m_NetServer.BanRemove(Addr); } +int CServer::BanRemoveAll() +{ + return m_NetServer.BanRemoveAll(); +} + void CServer::PumpNetwork() { @@ -1463,6 +1468,13 @@ void CServer::ConUnban(IConsole::IResult *pResult, void *pUser) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid network address"); } +void CServer::ConUnbanAll(IConsole::IResult *pResult, void *pUser) +{ + CServer *pServer = (CServer *)pUser; + if(!pServer->BanRemoveAll()) + pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "unbanned all"); +} + void CServer::ConBans(IConsole::IResult *pResult, void *pUser) { unsigned Now = time_timestamp(); @@ -1627,6 +1639,7 @@ void CServer::RegisterCommands() Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, "Kick player with specified id for any reason"); Console()->Register("ban", "s?ir", CFGFLAG_SERVER|CFGFLAG_STORE, ConBan, this, "Ban player with ip/id for x minutes for any reason"); Console()->Register("unban", "s", CFGFLAG_SERVER|CFGFLAG_STORE, ConUnban, this, "Unban ip"); + Console()->Register("unban_all", "", CFGFLAG_SERVER|CFGFLAG_STORE, ConUnbanAll, this, "Clear all bans"); Console()->Register("bans", "", CFGFLAG_SERVER|CFGFLAG_STORE, ConBans, this, "Show banlist"); Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "List players"); Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "Shut down"); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index d8fdd8fa..916eb37d 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -188,6 +188,7 @@ public: int BanAdd(NETADDR Addr, int Seconds, const char *pReason); int BanRemove(NETADDR Addr); + int BanRemoveAll(); void PumpNetwork(); @@ -200,6 +201,7 @@ public: static void ConKick(IConsole::IResult *pResult, void *pUser); static void ConBan(IConsole::IResult *pResult, void *pUser); static void ConUnban(IConsole::IResult *pResult, void *pUser); + static void ConUnbanAll(IConsole::IResult *pResult, void *pUser); static void ConBans(IConsole::IResult *pResult, void *pUser); static void ConStatus(IConsole::IResult *pResult, void *pUser); static void ConShutdown(IConsole::IResult *pResult, void *pUser); diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index d10c03b6..a9ace4e3 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -310,6 +310,7 @@ public: // banning int BanAdd(NETADDR Addr, int Seconds, const char *pReason); int BanRemove(NETADDR Addr); + int BanRemoveAll(); int BanNum(); // caution, slow int BanGet(int Index, CBanInfo *pInfo); // caution, slow diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index b100e1a2..b4986bf0 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -48,16 +48,7 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int for(int i = 0; i < NET_MAX_CLIENTS; i++) m_aSlots[i].m_Connection.Init(m_Socket); - // setup all pointers for bans - for(int i = 1; i < NET_SERVER_MAXBANS-1; i++) - { - m_BanPool[i].m_pNext = &m_BanPool[i+1]; - m_BanPool[i].m_pPrev = &m_BanPool[i-1]; - } - - m_BanPool[0].m_pNext = &m_BanPool[1]; - m_BanPool[NET_SERVER_MAXBANS-1].m_pPrev = &m_BanPool[NET_SERVER_MAXBANS-2]; - m_BanPool_FirstFree = &m_BanPool[0]; + BanRemoveAll(); return true; } @@ -146,6 +137,28 @@ int CNetServer::BanRemove(NETADDR Addr) return -1; } +int CNetServer::BanRemoveAll() +{ + // clear bans memory + mem_zero(m_aBans, sizeof(m_aBans)); + mem_zero(m_BanPool, sizeof(m_BanPool)); + m_BanPool_FirstFree = 0; + m_BanPool_FirstUsed = 0; + + // setup all pointers for bans + for(int i = 1; i < NET_SERVER_MAXBANS-1; i++) + { + m_BanPool[i].m_pNext = &m_BanPool[i+1]; + m_BanPool[i].m_pPrev = &m_BanPool[i-1]; + } + + m_BanPool[0].m_pNext = &m_BanPool[1]; + m_BanPool[NET_SERVER_MAXBANS-1].m_pPrev = &m_BanPool[NET_SERVER_MAXBANS-2]; + m_BanPool_FirstFree = &m_BanPool[0]; + + return 0; +} + int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason) { int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+ -- cgit 1.4.1 From 8e0ce38e299da43e4a9f55e45b3dcd1fbe462781 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 4 Dec 2011 16:51:33 +0100 Subject: fixed sv_max_client usage --- src/engine/server.h | 1 + src/engine/server/server.cpp | 5 +++++ src/engine/server/server.h | 1 + src/engine/shared/network.h | 2 +- src/game/server/gamecontext.cpp | 2 +- src/game/server/gamecontroller.cpp | 2 +- 6 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/server.h b/src/engine/server.h index 31134ca9..f3c9ca7c 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -25,6 +25,7 @@ public: int Tick() const { return m_CurrentGameTick; } int TickSpeed() const { return m_TickSpeed; } + virtual int MaxClients() const = 0; virtual const char *ClientName(int ClientID) = 0; virtual const char *ClientClan(int ClientID) = 0; virtual int ClientCountry(int ClientID) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index d253d3fc..a904f466 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -390,6 +390,11 @@ bool CServer::ClientIngame(int ClientID) return ClientID >= 0 && ClientID < MAX_CLIENTS && m_aClients[ClientID].m_State == CServer::CClient::STATE_INGAME; } +int CServer::MaxClients() const +{ + return m_NetServer.MaxClients(); +} + int CServer::SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) { return SendMsgEx(pMsg, Flags, ClientID, false); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 916eb37d..4c450a48 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -163,6 +163,7 @@ public: const char *ClientClan(int ClientID); int ClientCountry(int ClientID); bool ClientIngame(int ClientID); + int MaxClients() const; virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID); int SendMsgEx(CMsgPacker *pMsg, int Flags, int ClientID, bool System); diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index a9ace4e3..ca460d67 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -317,7 +317,7 @@ public: // status requests NETADDR ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } NETSOCKET Socket() const { return m_Socket; } - int NetType() { return m_Socket.type; } + int NetType() const { return m_Socket.type; } int MaxClients() const { return m_MaxClients; } // diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index b59a7244..dc993bfd 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -802,7 +802,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) else { char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "Only %d active players are allowed", g_Config.m_SvMaxClients-g_Config.m_SvSpectatorSlots); + str_format(aBuf, sizeof(aBuf), "Only %d active players are allowed", Server()->MaxClients()-g_Config.m_SvSpectatorSlots); SendBroadcast(aBuf, ClientID); } } diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index f8d418c3..3d582991 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -595,7 +595,7 @@ bool IGameController::CanJoinTeam(int Team, int NotThisID) } } - return (aNumplayers[0] + aNumplayers[1]) < g_Config.m_SvMaxClients-g_Config.m_SvSpectatorSlots; + return (aNumplayers[0] + aNumplayers[1]) < Server()->MaxClients()-g_Config.m_SvSpectatorSlots; } bool IGameController::CheckTeamBalance() -- cgit 1.4.1 From 4c73eab869b28fe1c580b74065347a787e89f21e Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 29 Dec 2011 13:34:13 +0100 Subject: fixed empty player names based on utf8 characters. Closes #904 --- src/engine/server/server.cpp | 46 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index a904f466..09891ba7 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -35,23 +35,45 @@ #include #endif -static const char *StrLtrim(const char *pStr) +static const char *StrUTF8Ltrim(const char *pStr) { - while(*pStr && *pStr >= 0 && *pStr <= 32) - pStr++; + while(*pStr) + { + const char *pStrOld = pStr; + int Code = str_utf8_decode(&pStr); + + // check if unicode is not empty + if(Code > 0x20 && Code != 0xA0 && Code != 0x034F && (Code < 0x2000 || Code > 0x200F) && (Code < 0x2028 || Code > 0x202F) && + (Code < 0x205F || Code > 0x2064) && (Code < 0x206A || Code > 0x206F) && (Code < 0xFE00 || Code > 0xFE0F) && + Code != 0xFEFF && (Code < 0xFFF9 || Code > 0xFFFC)) + { + return pStrOld; + } + } return pStr; } -static void StrRtrim(char *pStr) +static void StrUTF8Rtrim(char *pStr) { - int i = str_length(pStr); - while(i >= 0) + const char *p = pStr; + const char *pEnd = 0; + while(*p) { - if(pStr[i] < 0 || pStr[i] > 32) - break; - pStr[i] = 0; - i--; + const char *pStrOld = p; + int Code = str_utf8_decode(&p); + + // check if unicode is not empty + if(Code > 0x20 && Code != 0xA0 && Code != 0x034F && (Code < 0x2000 || Code > 0x200F) && (Code < 0x2028 || Code > 0x202F) && + (Code < 0x205F || Code > 0x2064) && (Code < 0x206A || Code > 0x206F) && (Code < 0xFE00 || Code > 0xFE0F) && + Code != 0xFEFF && (Code < 0xFFF9 || Code > 0xFFFC)) + { + pEnd = 0; + } + else if(pEnd == 0) + pEnd = pStrOld; } + if(pEnd != 0) + *(const_cast(pEnd)) = 0; } @@ -195,8 +217,8 @@ int CServer::TrySetClientName(int ClientID, const char *pName) char aTrimmedName[64]; // trim the name - str_copy(aTrimmedName, StrLtrim(pName), sizeof(aTrimmedName)); - StrRtrim(aTrimmedName); + str_copy(aTrimmedName, StrUTF8Ltrim(pName), sizeof(aTrimmedName)); + StrUTF8Rtrim(aTrimmedName); // check if new and old name are the same if(m_aClients[ClientID].m_aName[0] && str_comp(m_aClients[ClientID].m_aName, aTrimmedName) == 0) -- cgit 1.4.1 From b44ee3d9755ff35a6df1358dcfe85ce681bbe081 Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 29 Dec 2011 23:36:53 +0100 Subject: reworked ban system --- src/base/system.c | 22 +- src/base/system.h | 17 +- src/engine/client/client.cpp | 2 +- src/engine/client/serverbrowser.cpp | 11 +- src/engine/server/server.cpp | 331 ++++++----------- src/engine/server/server.h | 33 +- src/engine/shared/config.cpp | 7 +- src/engine/shared/console.cpp | 11 +- src/engine/shared/econ.cpp | 17 +- src/engine/shared/econ.h | 3 +- src/engine/shared/masterserver.cpp | 6 +- src/engine/shared/netban.cpp | 615 +++++++++++++++++++++++++++++++ src/engine/shared/netban.h | 184 +++++++++ src/engine/shared/network.h | 73 +--- src/engine/shared/network_console.cpp | 97 +---- src/engine/shared/network_server.cpp | 256 +------------ src/game/client/components/console.cpp | 8 +- src/game/client/components/maplayers.cpp | 7 +- src/mastersrv/mastersrv.cpp | 88 ++--- src/tools/crapnet.cpp | 4 +- src/tools/fake_server.cpp | 2 +- 21 files changed, 1060 insertions(+), 734 deletions(-) create mode 100644 src/engine/shared/netban.cpp create mode 100644 src/engine/shared/netban.h (limited to 'src/engine/server') diff --git a/src/base/system.c b/src/base/system.c index 7b60dab5..bf06a36e 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -125,7 +125,7 @@ static IOHANDLE logfile = 0; static void logger_file(const char *line) { io_write(logfile, line, strlen(line)); - io_write(logfile, "\n", 1); + io_write_newline(logfile); io_flush(logfile); } @@ -222,8 +222,9 @@ void mem_debug_dump(IOHANDLE file) { while(header) { - str_format(buf, sizeof(buf), "%s(%d): %d\n", header->filename, header->line, header->size); + str_format(buf, sizeof(buf), "%s(%d): %d", header->filename, header->line, header->size); io_write(file, buf, strlen(buf)); + io_write_newline(file); header = header->next; } @@ -346,6 +347,15 @@ unsigned io_write(IOHANDLE io, const void *buffer, unsigned size) return fwrite(buffer, 1, size, (FILE*)io); } +unsigned io_write_newline(IOHANDLE io) +{ +#if defined(CONF_FAMILY_WINDOWS) + return fwrite("\r\n", 1, 2, (FILE*)io); +#else + return fwrite("\n", 1, 1, (FILE*)io); +#endif +} + int io_close(IOHANDLE io) { fclose((FILE*)io); @@ -585,18 +595,18 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b) return mem_comp(a, b, sizeof(NETADDR)); } -void net_addr_str(const NETADDR *addr, char *string, int max_length) +void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port) { if(addr->type == NETTYPE_IPV4) { - if(addr->port != 0) + if(add_port != 0) str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port); else str_format(string, max_length, "%d.%d.%d.%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]); } else if(addr->type == NETTYPE_IPV6) { - if(addr->port != 0) + if(add_port != 0) str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", (addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7], (addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15], @@ -1500,7 +1510,7 @@ int net_socket_read_wait(NETSOCKET sock, int time) return 0; } -unsigned time_timestamp() +int time_timestamp() { return time(0); } diff --git a/src/base/system.h b/src/base/system.h index 749668de..5060fcb0 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -239,6 +239,18 @@ unsigned io_skip(IOHANDLE io, int size); */ unsigned io_write(IOHANDLE io, const void *buffer, unsigned size); +/* + Function: io_write_newline + Writes newline to file. + + Parameters: + io - Handle to the file. + + Returns: + Number of bytes written. +*/ +unsigned io_write_newline(IOHANDLE io); + /* Function: io_seek Seeks to a specified offset in the file. @@ -425,7 +437,7 @@ int64 time_freq(); Returns: The time as a UNIX timestamp */ -unsigned time_timestamp(); +int time_timestamp(); /* Group: Network General */ typedef struct @@ -499,12 +511,13 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b); addr - Address to turn into a string. string - Buffer to fill with the string. max_length - Maximum size of the string. + add_port - add port to string or not Remarks: - The string will always be zero terminated */ -void net_addr_str(const NETADDR *addr, char *string, int max_length); +void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port); /* Function: net_addr_from_str diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 9f43b9ce..c3bd770c 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -964,7 +964,7 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket) Info.m_NumPlayers < 0 || Info.m_NumPlayers > Info.m_NumClients || Info.m_MaxPlayers < 0 || Info.m_MaxPlayers > Info.m_MaxClients) return; - net_addr_str(&pPacket->m_Address, Info.m_aAddress, sizeof(Info.m_aAddress)); + net_addr_str(&pPacket->m_Address, Info.m_aAddress, sizeof(Info.m_aAddress), true); for(int i = 0; i < Info.m_NumClients; i++) { diff --git a/src/engine/client/serverbrowser.cpp b/src/engine/client/serverbrowser.cpp index 98a22d75..4dda9da9 100644 --- a/src/engine/client/serverbrowser.cpp +++ b/src/engine/client/serverbrowser.cpp @@ -387,7 +387,7 @@ CServerBrowser::CServerEntry *CServerBrowser::Add(const NETADDR &Addr) pEntry->m_Info.m_NetAddr = Addr; pEntry->m_Info.m_Latency = 999; - net_addr_str(&Addr, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aAddress)); + net_addr_str(&Addr, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aAddress), true); str_copy(pEntry->m_Info.m_aName, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aName)); // check if it's a favorite @@ -527,7 +527,7 @@ void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) cons if(g_Config.m_Debug) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf),"requesting server info from %s", aAddrStr); m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf); @@ -668,7 +668,7 @@ void CServerBrowser::AddFavorite(const NETADDR &Addr) if(g_Config.m_Debug) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "added fav, %s", aAddrStr); m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf); @@ -722,12 +722,11 @@ void CServerBrowser::ConfigSaveCallback(IConfig *pConfig, void *pUserData) { CServerBrowser *pSelf = (CServerBrowser *)pUserData; - int i; char aAddrStr[128]; char aBuffer[256]; - for(i = 0; i < pSelf->m_NumFavoriteServers; i++) + for(int i = 0; i < pSelf->m_NumFavoriteServers; i++) { - net_addr_str(&pSelf->m_aFavoriteServers[i], aAddrStr, sizeof(aAddrStr)); + net_addr_str(&pSelf->m_aFavoriteServers[i], aAddrStr, sizeof(aAddrStr), true); str_format(aBuffer, sizeof(aBuffer), "add_favorite %s", aAddrStr); pConfig->WriteLine(aBuffer); } diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 09891ba7..9587b94c 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -77,17 +78,6 @@ static void StrUTF8Rtrim(char *pStr) } -static int StrAllnum(const char *pStr) -{ - while(*pStr) - { - if(!(*pStr >= '0' && *pStr <= '9')) - return 0; - pStr++; - } - return 1; -} - CSnapIDPool::CSnapIDPool() { Reset(); @@ -176,6 +166,101 @@ void CSnapIDPool::FreeID(int ID) } } + +void CServerBan::Init(IConsole *pConsole, IStorage *pStorage, CServer* pServer) +{ + CNetBan::Init(pConsole, pStorage); + + m_pServer = pServer; + + // overwrites base command, todo: improve this + Console()->Register("ban", "s?ir", CFGFLAG_SERVER|CFGFLAG_STORE, ConBanExt, this, "Ban player with ip/client id for x minutes for any reason"); +} + +template +int CServerBan::BanExt(T *pBanPool, const typename T::CDataType *pData, int Seconds, const char *pReason) +{ + // validate address + if(Server()->m_RconClientID >= 0 && Server()->m_RconClientID < MAX_CLIENTS && + Server()->m_aClients[Server()->m_RconClientID].m_State != CServer::CClient::STATE_EMPTY) + { + if(NetMatch(pData, Server()->m_NetServer.ClientAddr(Server()->m_RconClientID))) + { + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban error (you can't ban yourself)"); + return -1; + } + + for(int i = 0; i < MAX_CLIENTS; ++i) + { + if(i == Server()->m_RconClientID || Server()->m_aClients[i].m_State == CServer::CClient::STATE_EMPTY) + continue; + + if(Server()->m_aClients[i].m_Authed >= Server()->m_RconAuthLevel && NetMatch(pData, Server()->m_NetServer.ClientAddr(i))) + { + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban error (command denied)"); + return -1; + } + } + } + + int Result = Ban(pBanPool, pData, Seconds, pReason); + if(Result != 0) + return Result; + + // drop banned clients + T::CDataType Data = *pData; + for(int i = 0; i < MAX_CLIENTS; ++i) + { + if(Server()->m_aClients[i].m_State == CServer::CClient::STATE_EMPTY) + continue; + + if(NetMatch(&Data, Server()->m_NetServer.ClientAddr(i))) + { + CNetHash NetHash(&Data); + char aBuf[256]; + MakeBanInfo(pBanPool->Find(&Data, &NetHash), aBuf, sizeof(aBuf), MSGTYPE_PLAYER); + Server()->m_NetServer.Drop(i, aBuf); + } + } + + return Result; +} + +int CServerBan::BanAddr(const NETADDR *pAddr, int Seconds, const char *pReason) +{ + return BanExt(&m_BanAddrPool, pAddr, Seconds, pReason); +} + +int CServerBan::BanRange(const CNetRange *pRange, int Seconds, const char *pReason) +{ + if(pRange->IsValid()) + return BanExt(&m_BanRangePool, pRange, Seconds, pReason); + + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban failed (invalid range)"); + return -1; +} + +void CServerBan::ConBanExt(IConsole::IResult *pResult, void *pUser) +{ + CServerBan *pThis = static_cast(pUser); + + const char *pStr = pResult->GetString(0); + int Minutes = pResult->NumArguments()>1 ? clamp(pResult->GetInteger(1), 0, 44640) : 30; + const char *pReason = pResult->NumArguments()>2 ? pResult->GetString(2) : "No reason given"; + + if(StrAllnum(pStr)) + { + int ClientID = str_toint(pStr); + if(ClientID < 0 || ClientID >= MAX_CLIENTS || pThis->Server()->m_aClients[ClientID].m_State == CServer::CClient::STATE_EMPTY) + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban error (invalid client id)"); + else + pThis->BanAddr(pThis->Server()->m_NetServer.ClientAddr(ClientID), Minutes*60, pReason); + } + else + ConBan(pResult, pUser); +} + + void CServer::CClient::Reset() { // reset input @@ -368,11 +453,7 @@ int CServer::GetClientInfo(int ClientID, CClientInfo *pInfo) void CServer::GetClientAddr(int ClientID, char *pAddrStr, int Size) { if(ClientID >= 0 && ClientID < MAX_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_INGAME) - { - NETADDR Addr = m_NetServer.ClientAddr(ClientID); - Addr.port = 0; - net_addr_str(&Addr, pAddrStr, Size); - } + net_addr_str(m_NetServer.ClientAddr(ClientID), pAddrStr, Size, false); } @@ -618,9 +699,8 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) { CServer *pThis = (CServer *)pUser; - NETADDR Addr = pThis->m_NetServer.ClientAddr(ClientID); char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(pThis->m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "client dropped. cid=%d addr=%s reason='%s'", ClientID, aAddrStr, pReason); pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); @@ -714,7 +794,6 @@ void CServer::UpdateClientRconCommands() void CServer::ProcessClientPacket(CNetChunk *pPacket) { int ClientID = pPacket->m_ClientID; - NETADDR Addr; CUnpacker Unpacker; Unpacker.Reset(pPacket->m_pData, pPacket->m_DataSize); @@ -793,9 +872,8 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) { if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTING) { - Addr = m_NetServer.ClientAddr(ClientID); char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x addr=%s", ClientID, aAddrStr); @@ -809,9 +887,8 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) { if(m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID)) { - Addr = m_NetServer.ClientAddr(ClientID); char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "player has entered the game. ClientID=%x addr=%s", ClientID, aAddrStr); @@ -945,10 +1022,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) if(!g_Config.m_SvRconBantime) m_NetServer.Drop(ClientID, "Too many remote console authentication tries"); else - { - NETADDR Addr = m_NetServer.ClientAddr(ClientID); - BanAdd(Addr, g_Config.m_SvRconBantime*60, "Too many remote console authentication tries"); - } + m_ServerBan.BanAddr(m_NetServer.ClientAddr(ClientID), g_Config.m_SvRconBantime*60, "Too many remote console authentication tries"); } } else @@ -992,7 +1066,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) } } -void CServer::SendServerInfo(NETADDR *pAddr, int Token) +void CServer::SendServerInfo(const NETADDR *pAddr, int Token) { CNetChunk Packet; CPacker p; @@ -1061,38 +1135,10 @@ void CServer::UpdateServerInfo() for(int i = 0; i < MAX_CLIENTS; ++i) { if(m_aClients[i].m_State != CClient::STATE_EMPTY) - { - NETADDR Addr = m_NetServer.ClientAddr(i); - SendServerInfo(&Addr, -1); - } + SendServerInfo(m_NetServer.ClientAddr(i), -1); } } -int CServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason) -{ - Addr.port = 0; - char aAddrStr[128]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); - char aBuf[256]; - if(Seconds) - str_format(aBuf, sizeof(aBuf), "banned %s for %d minutes", aAddrStr, Seconds/60); - else - str_format(aBuf, sizeof(aBuf), "banned %s for life", aAddrStr); - Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); - - return m_NetServer.BanAdd(Addr, Seconds, pReason); -} - -int CServer::BanRemove(NETADDR Addr) -{ - return m_NetServer.BanRemove(Addr); -} - -int CServer::BanRemoveAll() -{ - return m_NetServer.BanRemoveAll(); -} - void CServer::PumpNetwork() { @@ -1119,6 +1165,7 @@ void CServer::PumpNetwork() ProcessClientPacket(&Packet); } + m_ServerBan.Update(); m_Econ.Update(); } @@ -1217,7 +1264,7 @@ int CServer::Run() BindAddr.port = g_Config.m_SvPort; } - if(!m_NetServer.Open(BindAddr, g_Config.m_SvMaxClients, g_Config.m_SvMaxClientsPerIP, 0)) + if(!m_NetServer.Open(BindAddr, &m_ServerBan, g_Config.m_SvMaxClients, g_Config.m_SvMaxClientsPerIP, 0)) { dbg_msg("server", "couldn't open socket. port might already be in use"); return -1; @@ -1225,7 +1272,8 @@ int CServer::Run() m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this); - m_Econ.Init(Console()); + m_ServerBan.Init(Console(), Storage(), this); + m_Econ.Init(Console(), &m_ServerBan); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "server name is '%s'", g_Config.m_SvName); @@ -1388,170 +1436,23 @@ void CServer::ConKick(IConsole::IResult *pResult, void *pUser) ((CServer *)pUser)->Kick(pResult->GetInteger(0), "Kicked by console"); } -void CServer::ConBan(IConsole::IResult *pResult, void *pUser) -{ - NETADDR Addr; - CServer *pServer = (CServer *)pUser; - const char *pStr = pResult->GetString(0); - int Minutes = 30; - const char *pReason = "No reason given"; - - if(pResult->NumArguments() > 1) - Minutes = max(0, pResult->GetInteger(1)); - - if(pResult->NumArguments() > 2) - pReason = pResult->GetString(2); - - if(net_addr_from_str(&Addr, pStr) == 0) - { - if(pServer->m_RconClientID >= 0 && pServer->m_RconClientID < MAX_CLIENTS && pServer->m_aClients[pServer->m_RconClientID].m_State != CClient::STATE_EMPTY) - { - NETADDR AddrCheck = pServer->m_NetServer.ClientAddr(pServer->m_RconClientID); - Addr.port = AddrCheck.port = 0; - if(net_addr_comp(&Addr, &AddrCheck) == 0) - { - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "you can't ban yourself"); - return; - } - - for(int i = 0; i < MAX_CLIENTS; ++i) - { - if(i == pServer->m_RconClientID) - continue; - - AddrCheck = pServer->m_NetServer.ClientAddr(i); - AddrCheck.port = 0; - if(net_addr_comp(&Addr, &AddrCheck) == 0 && pServer->m_aClients[i].m_Authed > pServer->m_RconAuthLevel) - { - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "ban command denied"); - return; - } - } - } - pServer->BanAdd(Addr, Minutes*60, pReason); - } - else if(StrAllnum(pStr)) - { - int ClientID = str_toint(pStr); - - if(ClientID < 0 || ClientID >= MAX_CLIENTS || pServer->m_aClients[ClientID].m_State == CClient::STATE_EMPTY) - { - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid client id"); - return; - } - else if(pServer->m_RconClientID == ClientID) - { - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "you can't ban yourself"); - return; - } - else if(pServer->m_aClients[ClientID].m_Authed > pServer->m_RconAuthLevel) - { - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "ban command denied"); - return; - } - - Addr = pServer->m_NetServer.ClientAddr(ClientID); - pServer->BanAdd(Addr, Minutes*60, pReason); - } - else - { - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid network address to ban"); - return; - } -} - -void CServer::ConUnban(IConsole::IResult *pResult, void *pUser) -{ - NETADDR Addr; - CServer *pServer = (CServer *)pUser; - const char *pStr = pResult->GetString(0); - - if(net_addr_from_str(&Addr, pStr) == 0 && !pServer->BanRemove(Addr)) - { - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); - - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "unbanned %s", aAddrStr); - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); - } - else if(StrAllnum(pStr)) - { - int BanIndex = str_toint(pStr); - CNetServer::CBanInfo Info; - if(BanIndex < 0 || !pServer->m_NetServer.BanGet(BanIndex, &Info)) - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid ban index"); - else if(!pServer->BanRemove(Info.m_Addr)) - { - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Info.m_Addr, aAddrStr, sizeof(aAddrStr)); - - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "unbanned %s", aAddrStr); - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); - } - } - else - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid network address"); -} - -void CServer::ConUnbanAll(IConsole::IResult *pResult, void *pUser) -{ - CServer *pServer = (CServer *)pUser; - if(!pServer->BanRemoveAll()) - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "unbanned all"); -} - -void CServer::ConBans(IConsole::IResult *pResult, void *pUser) -{ - unsigned Now = time_timestamp(); - char aBuf[1024]; - char aAddrStr[NETADDR_MAXSTRSIZE]; - CServer* pServer = (CServer *)pUser; - - int Num = pServer->m_NetServer.BanNum(); - for(int i = 0; i < Num; i++) - { - CNetServer::CBanInfo Info; - pServer->m_NetServer.BanGet(i, &Info); - NETADDR Addr = Info.m_Addr; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); - - if(Info.m_Expires == -1) - { - str_format(aBuf, sizeof(aBuf), "#%i %s for life", i, aAddrStr); - } - else - { - unsigned t = Info.m_Expires - Now; - str_format(aBuf, sizeof(aBuf), "#%i %s for %d minutes and %d seconds", i, aAddrStr, t/60, t%60); - } - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); - } - str_format(aBuf, sizeof(aBuf), "%d ban(s)", Num); - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); -} - void CServer::ConStatus(IConsole::IResult *pResult, void *pUser) { - int i; - NETADDR Addr; char aBuf[1024]; char aAddrStr[NETADDR_MAXSTRSIZE]; - CServer* pServer = (CServer *)pUser; + CServer* pThis = static_cast(pUser); - for(i = 0; i < MAX_CLIENTS; i++) + for(int i = 0; i < MAX_CLIENTS; i++) { - if(pServer->m_aClients[i].m_State != CClient::STATE_EMPTY) + if(pThis->m_aClients[i].m_State != CClient::STATE_EMPTY) { - Addr = pServer->m_NetServer.ClientAddr(i); - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); - if(pServer->m_aClients[i].m_State == CClient::STATE_INGAME) + net_addr_str(pThis->m_NetServer.ClientAddr(i), aAddrStr, sizeof(aAddrStr), true); + if(pThis->m_aClients[i].m_State == CClient::STATE_INGAME) str_format(aBuf, sizeof(aBuf), "id=%d addr=%s name='%s' score=%d", i, aAddrStr, - pServer->m_aClients[i].m_aName, pServer->m_aClients[i].m_Score); + pThis->m_aClients[i].m_aName, pThis->m_aClients[i].m_Score); else str_format(aBuf, sizeof(aBuf), "id=%d addr=%s connecting", i, aAddrStr); - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); } } } @@ -1664,10 +1565,6 @@ void CServer::RegisterCommands() m_pConsole = Kernel()->RequestInterface(); Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, "Kick player with specified id for any reason"); - Console()->Register("ban", "s?ir", CFGFLAG_SERVER|CFGFLAG_STORE, ConBan, this, "Ban player with ip/id for x minutes for any reason"); - Console()->Register("unban", "s", CFGFLAG_SERVER|CFGFLAG_STORE, ConUnban, this, "Unban ip"); - Console()->Register("unban_all", "", CFGFLAG_SERVER|CFGFLAG_STORE, ConUnbanAll, this, "Clear all bans"); - Console()->Register("bans", "", CFGFLAG_SERVER|CFGFLAG_STORE, ConBans, this, "Show banlist"); Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "List players"); Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "Shut down"); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 4c450a48..2ff06a05 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -5,6 +5,7 @@ #include + class CSnapIDPool { enum @@ -39,6 +40,25 @@ public: void FreeID(int ID); }; + +class CServerBan : public CNetBan +{ + class CServer *m_pServer; + + template int BanExt(T *pBanPool, const typename T::CDataType *pData, int Seconds, const char *pReason); + +public: + class CServer *Server() const { return m_pServer; } + + void Init(class IConsole *pConsole, class IStorage *pStorage, class CServer* pServer); + + int BanAddr(const NETADDR *pAddr, int Seconds, const char *pReason); + int BanRange(const CNetRange *pRange, int Seconds, const char *pReason); + + static void ConBanExt(class IConsole::IResult *pResult, void *pUser); +}; + + class CServer : public IServer { class IGameServer *m_pGameServer; @@ -114,6 +134,7 @@ public: CSnapIDPool m_IDPool; CNetServer m_NetServer; CEcon m_Econ; + CServerBan m_ServerBan; IEngineMap *m_pMap; @@ -184,13 +205,9 @@ public: void ProcessClientPacket(CNetChunk *pPacket); - void SendServerInfo(NETADDR *pAddr, int Token); + void SendServerInfo(const NETADDR *pAddr, int Token); void UpdateServerInfo(); - int BanAdd(NETADDR Addr, int Seconds, const char *pReason); - int BanRemove(NETADDR Addr); - int BanRemoveAll(); - void PumpNetwork(); char *GetMapName(); @@ -200,11 +217,7 @@ public: int Run(); static void ConKick(IConsole::IResult *pResult, void *pUser); - static void ConBan(IConsole::IResult *pResult, void *pUser); - static void ConUnban(IConsole::IResult *pResult, void *pUser); - static void ConUnbanAll(IConsole::IResult *pResult, void *pUser); - static void ConBans(IConsole::IResult *pResult, void *pUser); - static void ConStatus(IConsole::IResult *pResult, void *pUser); + static void ConStatus(IConsole::IResult *pResult, void *pUser); static void ConShutdown(IConsole::IResult *pResult, void *pUser); static void ConRecord(IConsole::IResult *pResult, void *pUser); static void ConStopRecord(IConsole::IResult *pResult, void *pUser); diff --git a/src/engine/shared/config.cpp b/src/engine/shared/config.cpp index b9aa1320..d0cb7a6b 100644 --- a/src/engine/shared/config.cpp +++ b/src/engine/shared/config.cpp @@ -111,13 +111,8 @@ public: { if(!m_ConfigFile) return; -#if defined(CONF_FAMILY_WINDOWS) - static const char Newline[] = "\r\n"; -#else - static const char Newline[] = "\n"; -#endif io_write(m_ConfigFile, pLine, str_length(pLine)); - io_write(m_ConfigFile, Newline, sizeof(Newline)-1); + io_write_newline(m_ConfigFile); } }; diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index de5116c1..1b98a158 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -658,7 +658,13 @@ void CConsole::AddCommandSorted(CCommand *pCommand) void CConsole::Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) { - CCommand *pCommand = new(mem_alloc(sizeof(CCommand), sizeof(void*))) CCommand; + CCommand *pCommand = FindCommand(pName, Flags); + bool DoAdd = false; + if(pCommand == 0) + { + pCommand = new(mem_alloc(sizeof(CCommand), sizeof(void*))) CCommand; + DoAdd = true; + } pCommand->m_pfnCallback = pfnFunc; pCommand->m_pUserData = pUser; @@ -669,7 +675,8 @@ void CConsole::Register(const char *pName, const char *pParams, pCommand->m_Flags = Flags; pCommand->m_Temp = false; - AddCommandSorted(pCommand); + if(DoAdd) + AddCommandSorted(pCommand); } void CConsole::RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp index 617cdbd6..3eaf7aac 100644 --- a/src/engine/shared/econ.cpp +++ b/src/engine/shared/econ.cpp @@ -2,14 +2,15 @@ #include #include "econ.h" +#include "netban.h" + int CEcon::NewClientCallback(int ClientID, void *pUser) { CEcon *pThis = (CEcon *)pUser; - NETADDR Addr = pThis->m_NetConsole.ClientAddr(ClientID); char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(pThis->m_NetConsole.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[128]; str_format(aBuf, sizeof(aBuf), "client accepted. cid=%d addr=%s'", ClientID, aAddrStr); pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "econ", aBuf); @@ -26,9 +27,8 @@ int CEcon::DelClientCallback(int ClientID, const char *pReason, void *pUser) { CEcon *pThis = (CEcon *)pUser; - NETADDR Addr = pThis->m_NetConsole.ClientAddr(ClientID); char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(pThis->m_NetConsole.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "client dropped. cid=%d addr=%s reason='%s'", ClientID, aAddrStr, pReason); pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "econ", aBuf); @@ -52,7 +52,7 @@ void CEcon::ConchainEconOutputLevelUpdate(IConsole::IResult *pResult, void *pUse } } -void CEcon::Init(IConsole *pConsole) +void CEcon::Init(IConsole *pConsole, CNetBan *pNetBan) { m_pConsole = pConsole; @@ -74,7 +74,7 @@ void CEcon::Init(IConsole *pConsole) BindAddr.port = g_Config.m_EcPort; } - if(m_NetConsole.Open(BindAddr, 0)) + if(m_NetConsole.Open(BindAddr, pNetBan, 0)) { m_NetConsole.SetCallbacks(NewClientCallback, DelClientCallback, this); m_Ready = true; @@ -123,10 +123,7 @@ void CEcon::Update() if(!g_Config.m_EcBantime) m_NetConsole.Drop(ClientID, "Too many authentication tries"); else - { - NETADDR Addr = m_NetConsole.ClientAddr(ClientID); - m_NetConsole.AddBan(Addr, g_Config.m_EcBantime*60); - } + m_NetConsole.NetBan()->BanAddr(m_NetConsole.ClientAddr(ClientID), g_Config.m_EcBantime*60, "Too many authentication tries"); } } } diff --git a/src/engine/shared/econ.h b/src/engine/shared/econ.h index daec34c4..ed7d929b 100644 --- a/src/engine/shared/econ.h +++ b/src/engine/shared/econ.h @@ -3,6 +3,7 @@ #include "network.h" + class CEcon { enum @@ -41,7 +42,7 @@ class CEcon public: IConsole *Console() { return m_pConsole; } - void Init(IConsole *pConsole); + void Init(IConsole *pConsole, class CNetBan *pNetBan); void Update(); void Send(int ClientID, const char *pLine); void Shutdown(); diff --git a/src/engine/shared/masterserver.cpp b/src/engine/shared/masterserver.cpp index eb63bab5..95482639 100644 --- a/src/engine/shared/masterserver.cpp +++ b/src/engine/shared/masterserver.cpp @@ -192,13 +192,13 @@ public: { char aAddrStr[NETADDR_MAXSTRSIZE]; if(m_aMasterServers[i].m_Addr.type != NETTYPE_INVALID) - net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr), true); else aAddrStr[0] = 0; char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "%s %s\n", m_aMasterServers[i].m_aHostname, aAddrStr); - + str_format(aBuf, sizeof(aBuf), "%s %s", m_aMasterServers[i].m_aHostname, aAddrStr); io_write(File, aBuf, str_length(aBuf)); + io_write_newline(File); } io_close(File); diff --git a/src/engine/shared/netban.cpp b/src/engine/shared/netban.cpp new file mode 100644 index 00000000..eebe7c84 --- /dev/null +++ b/src/engine/shared/netban.cpp @@ -0,0 +1,615 @@ +#include + +#include +#include +#include + +#include "netban.h" + + +bool CNetBan::StrAllnum(const char *pStr) +{ + while(*pStr) + { + if(!(*pStr >= '0' && *pStr <= '9')) + return false; + pStr++; + } + return true; +} + + +CNetBan::CNetHash::CNetHash(const NETADDR *pAddr) +{ + if(pAddr->type==NETTYPE_IPV4) + m_Hash = (pAddr->ip[0]+pAddr->ip[1]+pAddr->ip[2]+pAddr->ip[3])&0xFF; + else + m_Hash = (pAddr->ip[0]+pAddr->ip[1]+pAddr->ip[2]+pAddr->ip[3]+pAddr->ip[4]+pAddr->ip[5]+pAddr->ip[6]+pAddr->ip[7]+ + pAddr->ip[8]+pAddr->ip[9]+pAddr->ip[10]+pAddr->ip[11]+pAddr->ip[12]+pAddr->ip[13]+pAddr->ip[14]+pAddr->ip[15])&0xFF; + m_HashIndex = 0; +} + +CNetBan::CNetHash::CNetHash(const CNetRange *pRange) +{ + m_Hash = 0; + m_HashIndex = 0; + for(int i = 0; pRange->m_LB.ip[i] == pRange->m_UB.ip[i]; ++i) + { + m_Hash += pRange->m_LB.ip[i]; + ++m_HashIndex; + } + m_Hash &= 0xFF; +} + +int CNetBan::CNetHash::MakeHashArray(const NETADDR *pAddr, CNetHash aHash[17]) +{ + int Length = pAddr->type==NETTYPE_IPV4 ? 4 : 16; + aHash[0].m_Hash = 0; + aHash[0].m_HashIndex = 0; + for(int i = 1, Sum = 0; i <= Length; ++i) + { + Sum += pAddr->ip[i-1]; + aHash[i].m_Hash = Sum&0xFF; + aHash[i].m_HashIndex = i%Length; + } + return Length; +} + + +template +typename CNetBan::CBan *CNetBan::CBanPool::Add(const T *pData, const CBanInfo *pInfo, const CNetHash *pNetHash) +{ + if(!m_pFirstFree) + return 0; + + // create new ban + CBan *pBan = m_pFirstFree; + pBan->m_Data = *pData; + pBan->m_Info = *pInfo; + pBan->m_NetHash = *pNetHash; + if(pBan->m_pNext) + pBan->m_pNext->m_pPrev = pBan->m_pPrev; + if(pBan->m_pPrev) + pBan->m_pPrev->m_pNext = pBan->m_pNext; + else + m_pFirstFree = pBan->m_pNext; + + // add it to the hash list + if(m_paaHashList[pNetHash->m_HashIndex][pNetHash->m_Hash]) + m_paaHashList[pNetHash->m_HashIndex][pNetHash->m_Hash]->m_pHashPrev = pBan; + pBan->m_pHashPrev = 0; + pBan->m_pHashNext = m_paaHashList[pNetHash->m_HashIndex][pNetHash->m_Hash]; + m_paaHashList[pNetHash->m_HashIndex][pNetHash->m_Hash] = pBan; + + // insert it into the used list + if(m_pFirstUsed) + { + for(CBan *p = m_pFirstUsed; ; p = p->m_pNext) + { + if(p->m_Info.m_Expires == CBanInfo::EXPIRES_NEVER || (pInfo->m_Expires != CBanInfo::EXPIRES_NEVER && pInfo->m_Expires <= p->m_Info.m_Expires)) + { + // insert before + pBan->m_pNext = p; + pBan->m_pPrev = p->m_pPrev; + if(p->m_pPrev) + p->m_pPrev->m_pNext = pBan; + else + m_pFirstUsed = pBan; + p->m_pPrev = pBan; + break; + } + + if(!p->m_pNext) + { + // last entry + p->m_pNext = pBan; + pBan->m_pPrev = p; + pBan->m_pNext = 0; + break; + } + } + } + else + { + m_pFirstUsed = pBan; + pBan->m_pNext = pBan->m_pPrev = 0; + } + + // update ban count + ++m_CountUsed; + + return pBan; +} + +template +int CNetBan::CBanPool::Remove(CBan *pBan) +{ + if(pBan == 0) + return -1; + + // remove from hash list + if(pBan->m_pHashNext) + pBan->m_pHashNext->m_pHashPrev = pBan->m_pHashPrev; + if(pBan->m_pHashPrev) + pBan->m_pHashPrev->m_pHashNext = pBan->m_pHashNext; + else + m_paaHashList[pBan->m_NetHash.m_HashIndex][pBan->m_NetHash.m_Hash] = pBan->m_pHashNext; + pBan->m_pHashNext = pBan->m_pHashPrev = 0; + + // remove from used list + if(pBan->m_pNext) + pBan->m_pNext->m_pPrev = pBan->m_pPrev; + if(pBan->m_pPrev) + pBan->m_pPrev->m_pNext = pBan->m_pNext; + else + m_pFirstUsed = pBan->m_pNext; + + // add to recycle list + if(m_pFirstFree) + m_pFirstFree->m_pPrev = pBan; + pBan->m_pPrev = 0; + pBan->m_pNext = m_pFirstFree; + m_pFirstFree = pBan; + + // update ban count + --m_CountUsed; + + return 0; +} + +template +void CNetBan::CBanPool::Update(CBan *pBan, const CBanInfo *pInfo) +{ + pBan->m_Info = *pInfo; + + // remove from used list + if(pBan->m_pNext) + pBan->m_pNext->m_pPrev = pBan->m_pPrev; + if(pBan->m_pPrev) + pBan->m_pPrev->m_pNext = pBan->m_pNext; + else + m_pFirstUsed = pBan->m_pNext; + + // insert it into the used list + if(m_pFirstUsed) + { + for(CBan *p = m_pFirstUsed; ; p = p->m_pNext) + { + if(p->m_Info.m_Expires == CBanInfo::EXPIRES_NEVER || (pInfo->m_Expires != CBanInfo::EXPIRES_NEVER && pInfo->m_Expires <= p->m_Info.m_Expires)) + { + // insert before + pBan->m_pNext = p; + pBan->m_pPrev = p->m_pPrev; + if(p->m_pPrev) + p->m_pPrev->m_pNext = pBan; + else + m_pFirstUsed = pBan; + p->m_pPrev = pBan; + break; + } + + if(!p->m_pNext) + { + // last entry + p->m_pNext = pBan; + pBan->m_pPrev = p; + pBan->m_pNext = 0; + break; + } + } + } + else + { + m_pFirstUsed = pBan; + pBan->m_pNext = pBan->m_pPrev = 0; + } +} + +template +void CNetBan::CBanPool::Reset() +{ + mem_zero(m_paaHashList, sizeof(m_paaHashList)); + mem_zero(m_aBans, sizeof(m_aBans)); + m_pFirstUsed = 0; + m_CountUsed = 0; + + for(int i = 1; i < MAX_BANS-1; ++i) + { + m_aBans[i].m_pNext = &m_aBans[i+1]; + m_aBans[i].m_pPrev = &m_aBans[i-1]; + } + + m_aBans[0].m_pNext = &m_aBans[1]; + m_aBans[MAX_BANS-1].m_pPrev = &m_aBans[MAX_BANS-2]; + m_pFirstFree = &m_aBans[0]; +} + +template +typename CNetBan::CBan *CNetBan::CBanPool::Find(const T *pData, const CNetHash *pNetHash) const +{ + for(CBan *pBan = m_paaHashList[pNetHash->m_HashIndex][pNetHash->m_Hash]; pBan; pBan = pBan->m_pHashNext) + { + if(NetComp(&pBan->m_Data, pData) == 0) + return pBan; + } + + return 0; +} + +template +typename CNetBan::CBan *CNetBan::CBanPool::Get(int Index) const +{ + if(Index < 0 || Index >= Num()) + return 0; + + for(CNetBan::CBan *pBan = m_pFirstUsed; pBan; pBan = pBan->m_pNext, --Index) + { + if(Index == 0) + return pBan; + } + + return 0; +} + + +template +void CNetBan::MakeBanInfo(const CBan *pBan, char *pBuf, unsigned BuffSize, int Type) const +{ + if(pBan == 0) + { + if(BuffSize > 0) + pBuf[0] = 0; + return; + } + + // build type based part + char aBuf[256]; + if(Type == MSGTYPE_PLAYER) + str_copy(aBuf, "You have been banned", sizeof(aBuf)); + else + { + char aTemp[256]; + switch(Type) + { + case MSGTYPE_LIST: + str_format(aBuf, sizeof(aBuf), "%s banned", NetToString(&pBan->m_Data, aTemp, sizeof(aTemp))); break; + case MSGTYPE_BANADD: + str_format(aBuf, sizeof(aBuf), "banned %s", NetToString(&pBan->m_Data, aTemp, sizeof(aTemp))); break; + case MSGTYPE_BANREM: + str_format(aBuf, sizeof(aBuf), "unbanned %s", NetToString(&pBan->m_Data, aTemp, sizeof(aTemp))); break; + default: + aBuf[0] = 0; + } + } + + // add info part + if(pBan->m_Info.m_Expires != CBanInfo::EXPIRES_NEVER) + { + int Mins = ((pBan->m_Info.m_Expires-time_timestamp()) + 59) / 60; + if(Mins <= 1) + str_format(pBuf, BuffSize, "%s for 1 minute (%s)", aBuf, pBan->m_Info.m_aReason); + else + str_format(pBuf, BuffSize, "%s for %d minutes (%s)", aBuf, Mins, pBan->m_Info.m_aReason); + } + else + str_format(pBuf, BuffSize, "%s for life (%s)", aBuf, pBan->m_Info.m_aReason); +} + +template +int CNetBan::Ban(T *pBanPool, const typename T::CDataType *pData, int Seconds, const char *pReason) +{ + // do not ban localhost + if(NetMatch(pData, &m_LocalhostIPV4) || NetMatch(pData, &m_LocalhostIPV6)) + { + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban failed (localhost)"); + return -1; + } + + int Stamp = Seconds > 0 ? time_timestamp()+Seconds : CBanInfo::EXPIRES_NEVER; + + // set up info + CBanInfo Info = {0}; + Info.m_Expires = Stamp; + str_copy(Info.m_aReason, pReason, sizeof(Info.m_aReason)); + + // check if it already exists + CNetHash NetHash(pData); + CBan *pBan = pBanPool->Find(pData, &NetHash); + if(pBan) + { + // adjust the ban + pBanPool->Update(pBan, &Info); + char aBuf[128]; + MakeBanInfo(pBan, aBuf, sizeof(aBuf), MSGTYPE_LIST); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); + return 1; + } + + // add ban and print result + pBan = pBanPool->Add(pData, &Info, &NetHash); + if(pBan) + { + char aBuf[128]; + MakeBanInfo(pBan, aBuf, sizeof(aBuf), MSGTYPE_BANADD); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); + return 0; + } + else + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban failed (full banlist)"); + return -1; +} + +template +int CNetBan::Unban(T *pBanPool, const typename T::CDataType *pData) +{ + CNetHash NetHash(pData); + CBan *pBan = pBanPool->Find(pData, &NetHash); + if(pBan) + { + char aBuf[256]; + MakeBanInfo(pBan, aBuf, sizeof(aBuf), MSGTYPE_BANREM); + pBanPool->Remove(pBan); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); + return 0; + } + else + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "unban failed (invalid entry)"); + return -1; +} + +void CNetBan::Init(IConsole *pConsole, IStorage *pStorage) +{ + m_pConsole = pConsole; + m_pStorage = pStorage; + m_BanAddrPool.Reset(); + m_BanRangePool.Reset(); + + net_host_lookup("localhost", &m_LocalhostIPV4, NETTYPE_IPV4); + net_host_lookup("localhost", &m_LocalhostIPV6, NETTYPE_IPV6); + + Console()->Register("ban", "s?ir", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConBan, this, "Ban ip for x minutes for any reason"); + Console()->Register("ban_range", "ss?ir", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConBanRange, this, "Ban ip range for x minutes for any reason"); + Console()->Register("unban", "s", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConUnban, this, "Unban ip/banlist entry"); + Console()->Register("unban_range", "ss", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConUnbanRange, this, "Unban ip range"); + Console()->Register("unban_all", "", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConUnbanAll, this, "Unban all entries"); + Console()->Register("bans", "", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConBans, this, "Show banlist"); + Console()->Register("bans_save", "s", CFGFLAG_SERVER|CFGFLAG_MASTER|CFGFLAG_STORE, ConBansSave, this, "Save banlist in a file"); +} + +void CNetBan::Update() +{ + int Now = time_timestamp(); + + // remove expired bans + char aBuf[256], aNetStr[256]; + while(m_BanAddrPool.First() && m_BanAddrPool.First()->m_Info.m_Expires != CBanInfo::EXPIRES_NEVER && m_BanAddrPool.First()->m_Info.m_Expires < Now) + { + str_format(aBuf, sizeof(aBuf), "ban %s expired", NetToString(&m_BanAddrPool.First()->m_Data, aNetStr, sizeof(aNetStr))); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); + m_BanAddrPool.Remove(m_BanAddrPool.First()); + } + while(m_BanRangePool.First() && m_BanRangePool.First()->m_Info.m_Expires != CBanInfo::EXPIRES_NEVER && m_BanRangePool.First()->m_Info.m_Expires < Now) + { + str_format(aBuf, sizeof(aBuf), "ban %s expired", NetToString(&m_BanRangePool.First()->m_Data, aNetStr, sizeof(aNetStr))); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); + m_BanRangePool.Remove(m_BanRangePool.First()); + } +} + +int CNetBan::BanAddr(const NETADDR *pAddr, int Seconds, const char *pReason) +{ + return Ban(&m_BanAddrPool, pAddr, Seconds, pReason); +} + +int CNetBan::BanRange(const CNetRange *pRange, int Seconds, const char *pReason) +{ + if(pRange->IsValid()) + return Ban(&m_BanRangePool, pRange, Seconds, pReason); + + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban failed (invalid range)"); + return -1; +} + +int CNetBan::UnbanByAddr(const NETADDR *pAddr) +{ + return Unban(&m_BanAddrPool, pAddr); +} + +int CNetBan::UnbanByRange(const CNetRange *pRange) +{ + if(pRange->IsValid()) + return Unban(&m_BanRangePool, pRange); + + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban failed (invalid range)"); + return -1; +} + +int CNetBan::UnbanByIndex(int Index) +{ + int Result; + char aBuf[256]; + CBanAddr *pBan = m_BanAddrPool.Get(Index); + if(pBan) + { + NetToString(&pBan->m_Data, aBuf, sizeof(aBuf)); + Result = m_BanAddrPool.Remove(pBan); + } + else + { + CBanRange *pBan = m_BanRangePool.Get(Index-m_BanAddrPool.Num()); + if(pBan) + { + NetToString(&pBan->m_Data, aBuf, sizeof(aBuf)); + Result = m_BanRangePool.Remove(pBan); + } + else + { + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "unban failed (invalid index)"); + return -1; + } + } + + char aMsg[256]; + str_format(aMsg, sizeof(aMsg), "unbanned index %i (%s)", Index, aBuf); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aMsg); + return Result; +} + +bool CNetBan::IsBanned(const NETADDR *pAddr, char *pBuf, unsigned BufferSize) const +{ + CNetHash aHash[17]; + int Length = CNetHash::MakeHashArray(pAddr, aHash); + + // check ban adresses + CBanAddr *pBan = m_BanAddrPool.Find(pAddr, &aHash[Length]); + if(pBan) + { + MakeBanInfo(pBan, pBuf, BufferSize, MSGTYPE_PLAYER); + return true; + } + + // check ban ranges + for(int i = Length-1; i >= 0; --i) + { + for(CBanRange *pBan = m_BanRangePool.First(&aHash[i]); pBan; pBan = pBan->m_pHashNext) + { + if(NetMatch(&pBan->m_Data, pAddr, i, Length)) + { + MakeBanInfo(pBan, pBuf, BufferSize, MSGTYPE_PLAYER); + return true; + } + } + } + + return false; +} + +void CNetBan::ConBan(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + const char *pStr = pResult->GetString(0); + int Minutes = pResult->NumArguments()>1 ? clamp(pResult->GetInteger(1), 0, 44640) : 30; + const char *pReason = pResult->NumArguments()>2 ? pResult->GetString(2) : "No reason given"; + + NETADDR Addr; + if(net_addr_from_str(&Addr, pStr) == 0) + pThis->BanAddr(&Addr, Minutes*60, pReason); + else + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban error (invalid network address)"); +} + +void CNetBan::ConBanRange(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + const char *pStr1 = pResult->GetString(0); + const char *pStr2 = pResult->GetString(1); + int Minutes = pResult->NumArguments()>2 ? clamp(pResult->GetInteger(2), 0, 44640) : 30; + const char *pReason = pResult->NumArguments()>3 ? pResult->GetString(3) : "No reason given"; + + CNetRange Range; + if(net_addr_from_str(&Range.m_LB, pStr1) == 0 && net_addr_from_str(&Range.m_UB, pStr2) == 0) + pThis->BanRange(&Range, Minutes*60, pReason); + else + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban error (invalid range)"); +} + +void CNetBan::ConUnban(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + const char *pStr = pResult->GetString(0); + if(StrAllnum(pStr)) + pThis->UnbanByIndex(str_toint(pStr)); + else + { + NETADDR Addr; + if(net_addr_from_str(&Addr, pStr) == 0) + pThis->UnbanByAddr(&Addr); + else + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "unban error (invalid network address)"); + } +} + +void CNetBan::ConUnbanRange(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + const char *pStr1 = pResult->GetString(0); + const char *pStr2 = pResult->GetString(1); + + CNetRange Range; + if(net_addr_from_str(&Range.m_LB, pStr1) == 0 && net_addr_from_str(&Range.m_UB, pStr2) == 0) + pThis->UnbanByRange(&Range); + else + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "unban error (invalid range)"); +} + +void CNetBan::ConUnbanAll(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + pThis->UnbanAll(); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "unbanned all entries"); +} + +void CNetBan::ConBans(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + int Count = 0; + char aBuf[256], aMsg[256]; + for(CBanAddr *pBan = pThis->m_BanAddrPool.First(); pBan; pBan = pBan->m_pNext) + { + pThis->MakeBanInfo(pBan, aBuf, sizeof(aBuf), MSGTYPE_LIST); + str_format(aMsg, sizeof(aMsg), "#%i %s", Count++, aBuf); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aMsg); + } + for(CBanRange *pBan = pThis->m_BanRangePool.First(); pBan; pBan = pBan->m_pNext) + { + pThis->MakeBanInfo(pBan, aBuf, sizeof(aBuf), MSGTYPE_LIST); + str_format(aMsg, sizeof(aMsg), "#%i %s", Count++, aBuf); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aMsg); + } + str_format(aMsg, sizeof(aMsg), "%d %s", Count, Count==1?"ban":"bans"); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aMsg); +} + +void CNetBan::ConBansSave(IConsole::IResult *pResult, void *pUser) +{ + CNetBan *pThis = static_cast(pUser); + + char aBuf[256]; + IOHANDLE File = pThis->Storage()->OpenFile(pResult->GetString(0), IOFLAG_WRITE, IStorage::TYPE_SAVE); + if(!File) + { + str_format(aBuf, sizeof(aBuf), "failed to save banlist to '%s'", pResult->GetString(0)); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); + return; + } + + int Now = time_timestamp(); + char aAddrStr1[NETADDR_MAXSTRSIZE], aAddrStr2[NETADDR_MAXSTRSIZE]; + for(CBanAddr *pBan = pThis->m_BanAddrPool.First(); pBan; pBan = pBan->m_pNext) + { + int Min = pBan->m_Info.m_Expires>-1 ? (pBan->m_Info.m_Expires-Now+59)/60 : -1; + net_addr_str(&pBan->m_Data, aAddrStr1, sizeof(aAddrStr1), false); + str_format(aBuf, sizeof(aBuf), "ban_ip %s %i %s", aAddrStr1, Min, pBan->m_Info.m_aReason); + io_write(File, aBuf, str_length(aBuf)); + io_write_newline(File); + } + for(CBanRange *pBan = pThis->m_BanRangePool.First(); pBan; pBan = pBan->m_pNext) + { + int Min = pBan->m_Info.m_Expires>-1 ? (pBan->m_Info.m_Expires-Now+59)/60 : -1; + net_addr_str(&pBan->m_Data.m_LB, aAddrStr1, sizeof(aAddrStr1), false); + net_addr_str(&pBan->m_Data.m_UB, aAddrStr2, sizeof(aAddrStr2), false); + str_format(aBuf, sizeof(aBuf), "ban_range %s %i %s", aAddrStr1, aAddrStr2, Min, pBan->m_Info.m_aReason); + io_write(File, aBuf, str_length(aBuf)); + io_write_newline(File); + } + + io_close(File); + str_format(aBuf, sizeof(aBuf), "saved banlist to '%s'", pResult->GetString(0)); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", aBuf); +} diff --git a/src/engine/shared/netban.h b/src/engine/shared/netban.h new file mode 100644 index 00000000..a93cc797 --- /dev/null +++ b/src/engine/shared/netban.h @@ -0,0 +1,184 @@ +#ifndef ENGINE_SHARED_NETBAN_H +#define ENGINE_SHARED_NETBAN_H + +#include + + +inline int NetComp(const NETADDR *pAddr1, const NETADDR *pAddr2) +{ + return mem_comp(pAddr1, pAddr2, pAddr1->type==NETTYPE_IPV4 ? 8 : 20); +} + +class CNetRange +{ +public: + NETADDR m_LB; + NETADDR m_UB; + + bool IsValid() const { return m_LB.type == m_UB.type && NetComp(&m_LB, &m_UB) < 0; } +}; + +inline int NetComp(const CNetRange *pRange1, const CNetRange *pRange2) +{ + return NetComp(&pRange1->m_LB, &pRange2->m_LB) || NetComp(&pRange1->m_UB, &pRange2->m_UB); +} + + +class CNetBan +{ +protected: + bool NetMatch(const NETADDR *pAddr1, const NETADDR *pAddr2) const + { + return NetComp(pAddr1, pAddr2) == 0; + } + + bool NetMatch(const CNetRange *pRange, const NETADDR *pAddr, int Start, int Length) const + { + return pRange->m_LB.type == pAddr->type && + mem_comp(&pRange->m_LB.ip[Start], &pAddr->ip[Start], Length-Start) <= 0 && mem_comp(&pRange->m_UB.ip[Start], &pAddr->ip[Start], Length-Start) >= 0; + } + + bool NetMatch(const CNetRange *pRange, const NETADDR *pAddr) const + { + return NetMatch(pRange, pAddr, 0, pRange->m_LB.type==NETTYPE_IPV4 ? 4 : 16); + } + + const char *NetToString(const NETADDR *pData, char *pBuffer, unsigned BufferSize) const + { + char aAddrStr[NETADDR_MAXSTRSIZE]; + net_addr_str(pData, aAddrStr, sizeof(aAddrStr), false); + str_format(pBuffer, BufferSize, "'%s'", aAddrStr); + return pBuffer; + } + + const char *NetToString(const CNetRange *pData, char *pBuffer, unsigned BufferSize) const + { + char aAddrStr1[NETADDR_MAXSTRSIZE], aAddrStr2[NETADDR_MAXSTRSIZE]; + net_addr_str(&pData->m_LB, aAddrStr1, sizeof(aAddrStr1), false); + net_addr_str(&pData->m_UB, aAddrStr2, sizeof(aAddrStr2), false); + str_format(pBuffer, BufferSize, "'%s' - '%s'", aAddrStr1, aAddrStr2); + return pBuffer; + } + + // todo: move? + static bool StrAllnum(const char *pStr); + + class CNetHash + { + public: + int m_Hash; + int m_HashIndex; // matching parts for ranges, 0 for addr + + CNetHash() {} + CNetHash(const NETADDR *pAddr); + CNetHash(const CNetRange *pRange); + + static int MakeHashArray(const NETADDR *pAddr, CNetHash aHash[17]); + }; + + struct CBanInfo + { + enum + { + EXPIRES_NEVER=-1, + REASON_LENGTH=64, + }; + int m_Expires; + char m_aReason[REASON_LENGTH]; + }; + + template struct CBan + { + T m_Data; + CBanInfo m_Info; + CNetHash m_NetHash; + + // hash list + CBan *m_pHashNext; + CBan *m_pHashPrev; + + // used or free list + CBan *m_pNext; + CBan *m_pPrev; + }; + + template class CBanPool + { + public: + typedef T CDataType; + + CBan *Add(const CDataType *pData, const CBanInfo *pInfo, const CNetHash *pNetHash); + int Remove(CBan *pBan); + void Update(CBan *pBan, const CBanInfo *pInfo); + void Reset(); + + int Num() const { return m_CountUsed; } + bool IsFull() const { return m_CountUsed == MAX_BANS; } + + CBan *First() const { return m_pFirstUsed; } + CBan *First(const CNetHash *pNetHash) const { return m_paaHashList[pNetHash->m_HashIndex][pNetHash->m_Hash]; } + CBan *Find(const CDataType *pData, const CNetHash *pNetHash) const; + CBan *Get(int Index) const; + + private: + enum + { + MAX_BANS=1024, + }; + + CBan *m_paaHashList[HashCount][256]; + CBan m_aBans[MAX_BANS]; + CBan *m_pFirstFree; + CBan *m_pFirstUsed; + int m_CountUsed; + }; + + typedef CBanPool CBanAddrPool; + typedef CBanPool CBanRangePool; + typedef CBan CBanAddr; + typedef CBan CBanRange; + + template void MakeBanInfo(const CBan *pBan, char *pBuf, unsigned BuffSize, int Type) const; + template int Ban(T *pBanPool, const typename T::CDataType *pData, int Seconds, const char *pReason); + template int Unban(T *pBanPool, const typename T::CDataType *pData); + + class IConsole *m_pConsole; + class IStorage *m_pStorage; + CBanAddrPool m_BanAddrPool; + CBanRangePool m_BanRangePool; + NETADDR m_LocalhostIPV4, m_LocalhostIPV6; + +public: + enum + { + MSGTYPE_PLAYER=0, + MSGTYPE_LIST, + MSGTYPE_BANADD, + MSGTYPE_BANREM, + }; + + class IConsole *Console() const { return m_pConsole; } + class IStorage *Storage() const { return m_pStorage; } + + virtual ~CNetBan() {} + virtual void Init(class IConsole *pConsole, class IStorage *pStorage); + void Update(); + + virtual int BanAddr(const NETADDR *pAddr, int Seconds, const char *pReason); + virtual int BanRange(const CNetRange *pRange, int Seconds, const char *pReason); + int UnbanByAddr(const NETADDR *pAddr); + int UnbanByRange(const CNetRange *pRange); + int UnbanByIndex(int Index); + void UnbanAll() { m_BanAddrPool.Reset(); m_BanRangePool.Reset(); } + bool IsBanned(const NETADDR *pAddr, char *pBuf, unsigned BufferSize) const; + + static void ConBan(class IConsole::IResult *pResult, void *pUser); + static void ConBanRange(class IConsole::IResult *pResult, void *pUser); + static void ConUnban(class IConsole::IResult *pResult, void *pUser); + static void ConUnbanRange(class IConsole::IResult *pResult, void *pUser); + static void ConUnbanAll(class IConsole::IResult *pResult, void *pUser); + static void ConBans(class IConsole::IResult *pResult, void *pUser); + static void ConBansSave(class IConsole::IResult *pResult, void *pUser); +}; + +#endif diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index ca460d67..dd43389e 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -73,8 +73,6 @@ enum NET_CTRLMSG_ACCEPT=3, NET_CTRLMSG_CLOSE=4, - NET_SERVER_MAXBANS=1024, - NET_CONN_BUFFERSIZE=1024*32, NET_ENUM_TERMINATOR @@ -182,7 +180,7 @@ public: const char *ErrorString(); void SignalResend(); int State() const { return m_State; } - NETADDR PeerAddress() const { return m_PeerAddr; } + const NETADDR *PeerAddress() const { return &m_PeerAddr; } void ResetErrorString() { m_ErrorString[0] = 0; } const char *ErrorString() const { return m_ErrorString; } @@ -214,7 +212,7 @@ public: void Disconnect(const char *pReason); int State() const { return m_State; } - NETADDR PeerAddress() const { return m_PeerAddr; } + const NETADDR *PeerAddress() const { return &m_PeerAddr; } const char *ErrorString() const { return m_aErrorString; } void Reset(); @@ -244,59 +242,29 @@ public: // server side class CNetServer { -public: - struct CBanInfo - { - NETADDR m_Addr; - int m_Expires; - char m_Reason[128]; - }; - -private: struct CSlot { public: CNetConnection m_Connection; }; - struct CBan - { - public: - CBanInfo m_Info; - - // hash list - CBan *m_pHashNext; - CBan *m_pHashPrev; - - // used or free list - CBan *m_pNext; - CBan *m_pPrev; - }; - - NETSOCKET m_Socket; + class CNetBan *m_pNetBan; CSlot m_aSlots[NET_MAX_CLIENTS]; int m_MaxClients; int m_MaxClientsPerIP; - CBan *m_aBans[256]; - CBan m_BanPool[NET_SERVER_MAXBANS]; - CBan *m_BanPool_FirstFree; - CBan *m_BanPool_FirstUsed; - NETFUNC_NEWCLIENT m_pfnNewClient; NETFUNC_DELCLIENT m_pfnDelClient; void *m_UserPtr; CNetRecvUnpacker m_RecvUnpacker; - void BanRemoveByObject(CBan *pBan); - public: int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); // - bool Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int Flags); + bool Open(NETADDR BindAddr, class CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags); int Close(); // @@ -307,16 +275,10 @@ public: // int Drop(int ClientID, const char *pReason); - // banning - int BanAdd(NETADDR Addr, int Seconds, const char *pReason); - int BanRemove(NETADDR Addr); - int BanRemoveAll(); - int BanNum(); // caution, slow - int BanGet(int Index, CBanInfo *pInfo); // caution, slow - // status requests - NETADDR ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } + const NETADDR *ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } NETSOCKET Socket() const { return m_Socket; } + class CNetBan *NetBan() const { return m_pNetBan; } int NetType() const { return m_Socket.type; } int MaxClients() const { return m_MaxClients; } @@ -326,27 +288,13 @@ public: class CNetConsole { - enum - { - MAX_BANS=128, - }; - - int FindBan(NETADDR Addr); - void UpdateBans(); - - struct CBanEntry - { - NETADDR m_Addr; - int m_Expires; - } m_aBans[MAX_BANS]; - int m_NumBans; - struct CSlot { CConsoleNetConnection m_Connection; }; NETSOCKET m_Socket; + class CNetBan *m_pNetBan; CSlot m_aSlots[NET_MAX_CONSOLE_CLIENTS]; NETFUNC_NEWCLIENT m_pfnNewClient; @@ -359,7 +307,7 @@ public: void SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); // - bool Open(NETADDR BindAddr, int Flags); + bool Open(NETADDR BindAddr, class CNetBan *pNetBan, int Flags); int Close(); // @@ -371,10 +319,9 @@ public: int AcceptClient(NETSOCKET Socket, const NETADDR *pAddr); int Drop(int ClientID, const char *pReason); - bool AddBan(NETADDR Addr, int Seconds); - // status requests - NETADDR ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } + const NETADDR *ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } + class CNetBan *NetBan() const { return m_pNetBan; } }; diff --git a/src/engine/shared/network_console.cpp b/src/engine/shared/network_console.cpp index cfa081a2..ded83f68 100644 --- a/src/engine/shared/network_console.cpp +++ b/src/engine/shared/network_console.cpp @@ -1,15 +1,21 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include + +#include + +#include "netban.h" #include "network.h" -bool CNetConsole::Open(NETADDR BindAddr, int Flags) + +bool CNetConsole::Open(NETADDR BindAddr, CNetBan *pNetBan, int Flags) { // zero out the whole structure mem_zero(this, sizeof(*this)); m_Socket.type = NETTYPE_INVALID; m_Socket.ipv4sock = -1; m_Socket.ipv6sock = -1; + m_pNetBan = pNetBan; // open socket m_Socket = net_tcp_create(BindAddr); @@ -64,8 +70,7 @@ int CNetConsole::AcceptClient(NETSOCKET Socket, const NETADDR *pAddr) FreeSlot = i; if(m_aSlots[i].m_Connection.State() != NET_CONNSTATE_OFFLINE) { - NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); - if(net_addr_comp(pAddr, &PeerAddr) == 0) + if(net_addr_comp(pAddr, m_aSlots[i].m_Connection.PeerAddress()) == 0) { str_copy(aError, "only one client per IP allowed", sizeof(aError)); break; @@ -99,26 +104,16 @@ int CNetConsole::Update() if(net_tcp_accept(m_Socket, &Socket, &Addr) > 0) { - int Index = FindBan(Addr); - if(Index == -1) - AcceptClient(Socket, &Addr); - else + // check if we just should drop the packet + char aBuf[128]; + if(NetBan() && NetBan()->IsBanned(&Addr, aBuf, sizeof(aBuf))) { - char aBuf[128]; - if(m_aBans[Index].m_Expires > -1) - { - int Mins = (m_aBans[Index].m_Expires-time_timestamp()+ 59) / 60; - if(Mins <= 1) - str_format(aBuf, sizeof(aBuf), "You have been banned for 1 minute"); - else - str_format(aBuf, sizeof(aBuf), "You have been banned for %d minutes", Mins); - } - else - str_format(aBuf, sizeof(aBuf), "You have been banned for life"); - + // banned, reply with a message and drop net_tcp_send(Socket, aBuf, str_length(aBuf)); net_tcp_close(Socket); } + else + AcceptClient(Socket, &Addr); } for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) @@ -129,8 +124,6 @@ int CNetConsole::Update() Drop(i, m_aSlots[i].m_Connection.ErrorString()); } - UpdateBans(); - return 0; } @@ -155,65 +148,3 @@ int CNetConsole::Send(int ClientID, const char *pLine) else return -1; } - -int CNetConsole::FindBan(NETADDR Addr) -{ - Addr.port = 0; - for(int i = 0; i < m_NumBans; i++) - if(net_addr_comp(&m_aBans[i].m_Addr, &Addr) == 0) - return i; - - return -1; -} - -bool CNetConsole::AddBan(NETADDR Addr, int Seconds) -{ - if(m_NumBans == MAX_BANS) - return false; - - Addr.port = 0; - int Index = FindBan(Addr); - if(Index == -1) - { - Index = m_NumBans++; - m_aBans[Index].m_Addr = Addr; - } - m_aBans[Index].m_Expires = Seconds>0 ? time_timestamp()+Seconds : -1; - - for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) - { - if(m_aSlots[i].m_Connection.State() != NET_CONNSTATE_OFFLINE) - { - NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); - PeerAddr.port = 0; - if(net_addr_comp(&Addr, &PeerAddr) == 0) - { - char aBuf[128]; - if(Seconds>0) - { - int Mins = (Seconds + 59) / 60; - if(Mins <= 1) - str_format(aBuf, sizeof(aBuf), "You have been banned for 1 minute"); - else - str_format(aBuf, sizeof(aBuf), "You have been banned for %d minutes", Mins); - } - else - str_format(aBuf, sizeof(aBuf), "You have been banned for life"); - Drop(i, aBuf); - } - } - } - return true; -} - -void CNetConsole::UpdateBans() -{ - int Now = time_timestamp(); - for(int i = 0; i < m_NumBans; ++i) - if(m_aBans[i].m_Expires > 0 && m_aBans[i].m_Expires < Now) - { - m_aBans[i] = m_aBans[m_NumBans-1]; - --m_NumBans; - break; - } -} diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index b4986bf0..1264a4a5 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -1,32 +1,14 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include -#include "network.h" -#define MACRO_LIST_LINK_FIRST(Object, First, Prev, Next) \ - { if(First) First->Prev = Object; \ - Object->Prev = (struct CBan *)0; \ - Object->Next = First; \ - First = Object; } - -#define MACRO_LIST_LINK_AFTER(Object, After, Prev, Next) \ - { Object->Prev = After; \ - Object->Next = After->Next; \ - After->Next = Object; \ - if(Object->Next) \ - Object->Next->Prev = Object; \ - } +#include -#define MACRO_LIST_UNLINK(Object, First, Prev, Next) \ - { if(Object->Next) Object->Next->Prev = Object->Prev; \ - if(Object->Prev) Object->Prev->Next = Object->Next; \ - else First = Object->Next; \ - Object->Next = 0; Object->Prev = 0; } +#include "netban.h" +#include "network.h" -#define MACRO_LIST_FIND(Start, Next, Expression) \ - { while(Start && !(Expression)) Start = Start->Next; } -bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int Flags) +bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure mem_zero(this, sizeof(*this)); @@ -36,6 +18,8 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int if(!m_Socket.type) return false; + m_pNetBan = pNetBan; + // clamp clients m_MaxClients = MaxClients; if(m_MaxClients > NET_MAX_CLIENTS) @@ -48,8 +32,6 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int for(int i = 0; i < NET_MAX_CLIENTS; i++) m_aSlots[i].m_Connection.Init(m_Socket); - BanRemoveAll(); - return true; } @@ -85,181 +67,8 @@ int CNetServer::Drop(int ClientID, const char *pReason) return 0; } -int CNetServer::BanGet(int Index, CBanInfo *pInfo) -{ - CBan *pBan; - for(pBan = m_BanPool_FirstUsed; pBan && Index; pBan = pBan->m_pNext, Index--) - {} - - if(!pBan) - return 0; - *pInfo = pBan->m_Info; - return 1; -} - -int CNetServer::BanNum() -{ - int Count = 0; - CBan *pBan; - for(pBan = m_BanPool_FirstUsed; pBan; pBan = pBan->m_pNext) - Count++; - return Count; -} - -void CNetServer::BanRemoveByObject(CBan *pBan) -{ - int IpHash = (pBan->m_Info.m_Addr.ip[0]+pBan->m_Info.m_Addr.ip[1]+pBan->m_Info.m_Addr.ip[2]+pBan->m_Info.m_Addr.ip[3]+ - pBan->m_Info.m_Addr.ip[4]+pBan->m_Info.m_Addr.ip[5]+pBan->m_Info.m_Addr.ip[6]+pBan->m_Info.m_Addr.ip[7]+ - pBan->m_Info.m_Addr.ip[8]+pBan->m_Info.m_Addr.ip[9]+pBan->m_Info.m_Addr.ip[10]+pBan->m_Info.m_Addr.ip[11]+ - pBan->m_Info.m_Addr.ip[12]+pBan->m_Info.m_Addr.ip[13]+pBan->m_Info.m_Addr.ip[14]+pBan->m_Info.m_Addr.ip[15])&0xff; - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&pBan->m_Info.m_Addr, aAddrStr, sizeof(aAddrStr)); - dbg_msg("netserver", "removing ban on %s", aAddrStr); - MACRO_LIST_UNLINK(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext); - MACRO_LIST_UNLINK(pBan, m_aBans[IpHash], m_pHashPrev, m_pHashNext); - MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstFree, m_pPrev, m_pNext); -} - -int CNetServer::BanRemove(NETADDR Addr) -{ - int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+ - Addr.ip[8]+Addr.ip[9]+Addr.ip[10]+Addr.ip[11]+Addr.ip[12]+Addr.ip[13]+Addr.ip[14]+Addr.ip[15])&0xff; - CBan *pBan = m_aBans[IpHash]; - - MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0); - - if(pBan) - { - BanRemoveByObject(pBan); - return 0; - } - - return -1; -} - -int CNetServer::BanRemoveAll() -{ - // clear bans memory - mem_zero(m_aBans, sizeof(m_aBans)); - mem_zero(m_BanPool, sizeof(m_BanPool)); - m_BanPool_FirstFree = 0; - m_BanPool_FirstUsed = 0; - - // setup all pointers for bans - for(int i = 1; i < NET_SERVER_MAXBANS-1; i++) - { - m_BanPool[i].m_pNext = &m_BanPool[i+1]; - m_BanPool[i].m_pPrev = &m_BanPool[i-1]; - } - - m_BanPool[0].m_pNext = &m_BanPool[1]; - m_BanPool[NET_SERVER_MAXBANS-1].m_pPrev = &m_BanPool[NET_SERVER_MAXBANS-2]; - m_BanPool_FirstFree = &m_BanPool[0]; - - return 0; -} - -int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason) -{ - int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+ - Addr.ip[8]+Addr.ip[9]+Addr.ip[10]+Addr.ip[11]+Addr.ip[12]+Addr.ip[13]+Addr.ip[14]+Addr.ip[15])&0xff; - int Stamp = -1; - CBan *pBan; - - // remove the port - Addr.port = 0; - - if(Seconds) - Stamp = time_timestamp() + Seconds; - - // search to see if it already exists - pBan = m_aBans[IpHash]; - MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0); - if(pBan) - { - // adjust the ban - pBan->m_Info.m_Expires = Stamp; - return 0; - } - - if(!m_BanPool_FirstFree) - return -1; - - // fetch and clear the new ban - pBan = m_BanPool_FirstFree; - MACRO_LIST_UNLINK(pBan, m_BanPool_FirstFree, m_pPrev, m_pNext); - - // setup the ban info - pBan->m_Info.m_Expires = Stamp; - pBan->m_Info.m_Addr = Addr; - str_copy(pBan->m_Info.m_Reason, pReason, sizeof(pBan->m_Info.m_Reason)); - - // add it to the ban hash - MACRO_LIST_LINK_FIRST(pBan, m_aBans[IpHash], m_pHashPrev, m_pHashNext); - - // insert it into the used list - { - if(m_BanPool_FirstUsed) - { - CBan *pInsertAfter = m_BanPool_FirstUsed; - MACRO_LIST_FIND(pInsertAfter, m_pNext, Stamp < pInsertAfter->m_Info.m_Expires); - - if(pInsertAfter) - pInsertAfter = pInsertAfter->m_pPrev; - else - { - // add to last - pInsertAfter = m_BanPool_FirstUsed; - while(pInsertAfter->m_pNext) - pInsertAfter = pInsertAfter->m_pNext; - } - - if(pInsertAfter) - { - MACRO_LIST_LINK_AFTER(pBan, pInsertAfter, m_pPrev, m_pNext); - } - else - { - MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext); - } - } - else - { - MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext); - } - } - - // drop banned clients - { - char Buf[128]; - NETADDR BanAddr; - - if(Stamp > -1) - { - int Mins = (Seconds + 59) / 60; - if(Mins <= 1) - str_format(Buf, sizeof(Buf), "You have been banned for 1 minute (%s)", pReason); - else - str_format(Buf, sizeof(Buf), "You have been banned for %d minutes (%s)", Mins, pReason); - } - else - str_format(Buf, sizeof(Buf), "You have been banned for life (%s)", pReason); - - for(int i = 0; i < MaxClients(); i++) - { - BanAddr = m_aSlots[i].m_Connection.PeerAddress(); - BanAddr.port = 0; - - if(net_addr_comp(&Addr, &BanAddr) == 0) - Drop(i, Buf); - } - } - return 0; -} - int CNetServer::Update() { - int Now = time_timestamp(); for(int i = 0; i < MaxClients(); i++) { m_aSlots[i].m_Connection.Update(); @@ -267,13 +76,6 @@ int CNetServer::Update() Drop(i, m_aSlots[i].m_Connection.ErrorString()); } - // remove expired bans - while(m_BanPool_FirstUsed && m_BanPool_FirstUsed->m_Info.m_Expires > -1 && m_BanPool_FirstUsed->m_Info.m_Expires < Now) - { - CBan *pBan = m_BanPool_FirstUsed; - BanRemoveByObject(pBan); - } - return 0; } @@ -282,8 +84,6 @@ int CNetServer::Update() */ int CNetServer::Recv(CNetChunk *pChunk) { - unsigned Now = time_timestamp(); - while(1) { NETADDR Addr; @@ -301,36 +101,12 @@ int CNetServer::Recv(CNetChunk *pChunk) if(CNetBase::UnpackPacket(m_RecvUnpacker.m_aBuffer, Bytes, &m_RecvUnpacker.m_Data) == 0) { - CBan *pBan = 0; - NETADDR BanAddr = Addr; - int IpHash = (BanAddr.ip[0]+BanAddr.ip[1]+BanAddr.ip[2]+BanAddr.ip[3]+BanAddr.ip[4]+BanAddr.ip[5]+BanAddr.ip[6]+BanAddr.ip[7]+ - BanAddr.ip[8]+BanAddr.ip[9]+BanAddr.ip[10]+BanAddr.ip[11]+BanAddr.ip[12]+BanAddr.ip[13]+BanAddr.ip[14]+BanAddr.ip[15])&0xff; - int Found = 0; - BanAddr.port = 0; - - // search a ban - for(pBan = m_aBans[IpHash]; pBan; pBan = pBan->m_pHashNext) - { - if(net_addr_comp(&pBan->m_Info.m_Addr, &BanAddr) == 0) - break; - } - // check if we just should drop the packet - if(pBan) + char aBuf[128]; + if(NetBan() && NetBan()->IsBanned(&Addr, aBuf, sizeof(aBuf))) { // banned, reply with a message - char BanStr[128]; - if(pBan->m_Info.m_Expires > -1) - { - int Mins = ((pBan->m_Info.m_Expires - Now)+59)/60; - if(Mins <= 1) - str_format(BanStr, sizeof(BanStr), "Banned for 1 minute (%s)", pBan->m_Info.m_Reason); - else - str_format(BanStr, sizeof(BanStr), "Banned for %d minutes (%s)", Mins, pBan->m_Info.m_Reason); - } - else - str_format(BanStr, sizeof(BanStr), "Banned for life (%s)", pBan->m_Info.m_Reason); - CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, BanStr, str_length(BanStr)+1); + CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, str_length(aBuf)+1); continue; } @@ -348,16 +124,15 @@ int CNetServer::Recv(CNetChunk *pChunk) // TODO: check size here if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && m_RecvUnpacker.m_Data.m_aChunkData[0] == NET_CTRLMSG_CONNECT) { - Found = 0; + bool Found = false; // check if we already got this client for(int i = 0; i < MaxClients(); i++) { - NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); if(m_aSlots[i].m_Connection.State() != NET_CONNSTATE_OFFLINE && - net_addr_comp(&PeerAddr, &Addr) == 0) + net_addr_comp(m_aSlots[i].m_Connection.PeerAddress(), &Addr) == 0) { - Found = 1; // silent ignore.. we got this client already + Found = true; // silent ignore.. we got this client already break; } } @@ -374,7 +149,7 @@ int CNetServer::Recv(CNetChunk *pChunk) if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE) continue; - OtherAddr = m_aSlots[i].m_Connection.PeerAddress(); + OtherAddr = *m_aSlots[i].m_Connection.PeerAddress(); OtherAddr.port = 0; if(!net_addr_comp(&ThisAddr, &OtherAddr)) { @@ -392,7 +167,7 @@ int CNetServer::Recv(CNetChunk *pChunk) { if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE) { - Found = 1; + Found = true; m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr); if(m_pfnNewClient) m_pfnNewClient(i, m_UserPtr); @@ -412,8 +187,7 @@ int CNetServer::Recv(CNetChunk *pChunk) // normal packet, find matching slot for(int i = 0; i < MaxClients(); i++) { - NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); - if(net_addr_comp(&PeerAddr, &Addr) == 0) + if(net_addr_comp(m_aSlots[i].m_Connection.PeerAddress(), &Addr) == 0) { if(m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr)) { diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index f2e9e65d..d16d56cd 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -612,16 +612,10 @@ void CGameConsole::Dump(int Type) IOHANDLE io = Storage()->OpenFile(aFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE); if(io) { - #if defined(CONF_FAMILY_WINDOWS) - static const char Newline[] = "\r\n"; - #else - static const char Newline[] = "\n"; - #endif - for(CInstance::CBacklogEntry *pEntry = pConsole->m_Backlog.First(); pEntry; pEntry = pConsole->m_Backlog.Next(pEntry)) { io_write(io, pEntry->m_aText, str_length(pEntry->m_aText)); - io_write(io, Newline, sizeof(Newline)-1); + io_write_newline(io); } io_close(io); } diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index a1e629a6..f0460d26 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -188,16 +188,11 @@ void CMapLayers::OnRender() IOHANDLE File = Storage()->OpenFile(aFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE); if(File) { - #if defined(CONF_FAMILY_WINDOWS) - static const char Newline[] = "\r\n"; - #else - static const char Newline[] = "\n"; - #endif for(int y = 0; y < pTMap->m_Height; y++) { for(int x = 0; x < pTMap->m_Width; x++) io_write(File, &(pTiles[y*pTMap->m_Width + x].m_Index), sizeof(pTiles[y*pTMap->m_Width + x].m_Index)); - io_write(File, Newline, sizeof(Newline)-1); + io_write_newline(File); } io_close(File); } diff --git a/src/mastersrv/mastersrv.cpp b/src/mastersrv/mastersrv.cpp index 70e4aecf..632a524c 100644 --- a/src/mastersrv/mastersrv.cpp +++ b/src/mastersrv/mastersrv.cpp @@ -1,20 +1,23 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include -#include -#include + #include -#include #include +#include + +#include +#include +#include #include "mastersrv.h" + enum { MTU = 1400, MAX_SERVERS_PER_PACKET=75, MAX_PACKETS=16, MAX_SERVERS=MAX_SERVERS_PER_PACKET*MAX_PACKETS, - MAX_BANS=128, EXPIRE_TIME = 90 }; @@ -77,14 +80,7 @@ static CCountPacketData m_CountData; static CCountPacketData m_CountDataLegacy; -struct CBanEntry -{ - NETADDR m_Address; - int64 m_Expire; -}; - -static CBanEntry m_aBans[MAX_BANS]; -static int m_NumBans = 0; +CNetBan m_NetBan; static CNetClient m_NetChecker; // NAT/FW checker static CNetClient m_NetOp; // main @@ -217,9 +213,9 @@ void AddCheckserver(NETADDR *pInfo, NETADDR *pAlt, ServerType Type) } char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr)); + net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr), true); char aAltAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pAlt, aAltAddrStr, sizeof(aAltAddrStr)); + net_addr_str(pAlt, aAltAddrStr, sizeof(aAltAddrStr), true); dbg_msg("mastersrv", "checking: %s (%s)", aAddrStr, aAltAddrStr); m_aCheckServers[m_NumCheckServers].m_Address = *pInfo; m_aCheckServers[m_NumCheckServers].m_AltAddress = *pAlt; @@ -237,7 +233,7 @@ void AddServer(NETADDR *pInfo, ServerType Type) if(net_addr_comp(&m_aServers[i].m_Address, pInfo) == 0) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr)); + net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr), true); dbg_msg("mastersrv", "updated: %s", aAddrStr); m_aServers[i].m_Expire = time_get()+time_freq()*EXPIRE_TIME; return; @@ -252,7 +248,7 @@ void AddServer(NETADDR *pInfo, ServerType Type) } char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr)); + net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr), true); dbg_msg("mastersrv", "added: %s", aAddrStr); m_aServers[m_NumServers].m_Address = *pInfo; m_aServers[m_NumServers].m_Expire = time_get()+time_freq()*EXPIRE_TIME; @@ -271,9 +267,9 @@ void UpdateServers() if(m_aCheckServers[i].m_TryCount == 10) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aCheckServers[i].m_Address, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&m_aCheckServers[i].m_Address, aAddrStr, sizeof(aAddrStr), true); char aAltAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aCheckServers[i].m_AltAddress, aAltAddrStr, sizeof(aAltAddrStr)); + net_addr_str(&m_aCheckServers[i].m_AltAddress, aAltAddrStr, sizeof(aAltAddrStr), true); dbg_msg("mastersrv", "check failed: %s (%s)", aAddrStr, aAltAddrStr); // FAIL!! @@ -305,7 +301,7 @@ void PurgeServers() { // remove server char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aServers[i].m_Address, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&m_aServers[i].m_Address, aAddrStr, sizeof(aAddrStr), true); dbg_msg("mastersrv", "expired: %s", aAddrStr); m_aServers[i] = m_aServers[m_NumServers-1]; m_NumServers--; @@ -315,53 +311,9 @@ void PurgeServers() } } -bool CheckBan(NETADDR Addr) -{ - for(int i = 0; i < m_NumBans; i++) - { - if(net_addr_comp(&m_aBans[i].m_Address, &Addr) == 0) - { - return true; - } - } - Addr.port = 0; - for(int i = 0; i < m_NumBans; i++) - { - if(net_addr_comp(&m_aBans[i].m_Address, &Addr) == 0) - { - return true; - } - } - return false; -} - -void ConAddBan(IConsole::IResult *pResult, void *pUser) -{ - if(m_NumBans == MAX_BANS) - { - dbg_msg("mastersrv", "error: banlist is full"); - return; - } - - if(net_addr_from_str(&m_aBans[m_NumBans].m_Address, pResult->GetString(0)) != 0) - { - dbg_msg("mastersrv", "error: invalid address"); - return; - } - - if(CheckBan(m_aBans[m_NumBans].m_Address)) - { - dbg_msg("mastersrv", "duplicate ban: %s", pResult->GetString(0)); - return; - } - - dbg_msg("mastersrv", "ban added: %s", pResult->GetString(0)); - m_NumBans++; -} - void ReloadBans() { - m_NumBans = 0; + m_NetBan.UnbanAll(); m_pConsole->ExecuteFile("master.cfg"); } @@ -398,7 +350,7 @@ int main(int argc, const char **argv) // ignore_convention IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); m_pConsole = CreateConsole(CFGFLAG_MASTER); - m_pConsole->Register("ban", "s", CFGFLAG_MASTER, ConAddBan, 0, "Ban IP from mastersrv"); + m_NetBan.Init(m_pConsole, pStorage); bool RegisterFail = !pKernel->RegisterInterface(pStorage); RegisterFail |= !pKernel->RegisterInterface(m_pConsole); @@ -418,7 +370,8 @@ int main(int argc, const char **argv) // ignore_convention while(m_NetOp.Recv(&Packet)) { // check if the server is banned - if(CheckBan(Packet.m_Address)) continue; + if(m_NetBan.IsBanned(&Packet.m_Address, 0, 0)) + continue; if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT)+2 && mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0) @@ -519,7 +472,8 @@ int main(int argc, const char **argv) // ignore_convention while(m_NetChecker.Recv(&Packet)) { // check if the server is banned - if(CheckBan(Packet.m_Address)) continue; + if(m_NetBan.IsBanned(&Packet.m_Address, 0, 0)) + continue; if(Packet.m_DataSize == sizeof(SERVERBROWSE_FWRESPONSE) && mem_comp(Packet.m_pData, SERVERBROWSE_FWRESPONSE, sizeof(SERVERBROWSE_FWRESPONSE)) == 0) diff --git a/src/tools/crapnet.cpp b/src/tools/crapnet.cpp index 98b6c0a7..fbd20445 100644 --- a/src/tools/crapnet.cpp +++ b/src/tools/crapnet.cpp @@ -129,7 +129,7 @@ void Run(int Port, NETADDR Dest) if(m_ConfigLog) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&From, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&From, aAddrStr, sizeof(aAddrStr), true); dbg_msg("crapnet", "<< %08d %s (%d)", p->m_ID, aAddrStr, p->m_DataSize); } } @@ -193,7 +193,7 @@ void Run(int Port, NETADDR Dest) if(m_ConfigLog) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&p->m_SendTo, aAddrStr, sizeof(aAddrStr)); + net_addr_str(&p->m_SendTo, aAddrStr, sizeof(aAddrStr), true); dbg_msg("crapnet", ">> %08d %s (%d) %s", p->m_ID, aAddrStr, p->m_DataSize, aFlags); } diff --git a/src/tools/fake_server.cpp b/src/tools/fake_server.cpp index 68c47659..9e76b3e7 100644 --- a/src/tools/fake_server.cpp +++ b/src/tools/fake_server.cpp @@ -113,7 +113,7 @@ static int Run() int64 NextHeartBeat = 0; NETADDR BindAddr = {NETTYPE_IPV4, {0},0}; - if(!pNet->Open(BindAddr, 0, 0, 0)) + if(!pNet->Open(BindAddr, 0, 0, 0, 0)) return 0; while(1) -- cgit 1.4.1 From 81e6cf6f83b8f45705f4c2a76ca4a1e647a3c4a2 Mon Sep 17 00:00:00 2001 From: Learath2 Date: Mon, 26 Dec 2011 23:07:57 +0200 Subject: Added logout command. Closes #903 --- src/engine/server/server.cpp | 17 +++++++++++++++++ src/engine/server/server.h | 1 + 2 files changed, 18 insertions(+) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 9587b94c..9bb36b74 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1507,6 +1507,22 @@ void CServer::ConMapReload(IConsole::IResult *pResult, void *pUser) ((CServer *)pUser)->m_MapReload = 1; } +void CServer::ConLogout(IConsole::IResult *pResult, void *pUser) +{ + CServer *pServer = (CServer *)pUser; + + CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); + Msg.AddInt(0); //authed + Msg.AddInt(0); //cmdlist + pServer->SendMsgEx(&Msg, MSGFLAG_VITAL, pServer->m_RconClientID, true); + + pServer->m_aClients[pServer->m_RconClientID].m_Authed = AUTHED_NO; + pServer->SendRconLine(pServer->m_RconClientID, "You've logged out"); + char aBuf[32]; + str_format(aBuf, sizeof(aBuf), "ClientID=%d logged out", pServer->m_RconClientID); + pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); +} + void CServer::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) { pfnCallback(pResult, pCallbackUserData); @@ -1567,6 +1583,7 @@ void CServer::RegisterCommands() Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, "Kick player with specified id for any reason"); Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "List players"); Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "Shut down"); + Console()->Register("logout", "", CFGFLAG_SERVER, ConLogout, this, "Logs you out of Rcon"); Console()->Register("record", "?s", CFGFLAG_SERVER|CFGFLAG_STORE, ConRecord, this, "Record to a file"); Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, "Stop recording"); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 2ff06a05..fe79a3da 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -222,6 +222,7 @@ public: static void ConRecord(IConsole::IResult *pResult, void *pUser); static void ConStopRecord(IConsole::IResult *pResult, void *pUser); static void ConMapReload(IConsole::IResult *pResult, void *pUser); + static void ConLogout(IConsole::IResult *pResult, void *pUser); static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainModCommandUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); -- cgit 1.4.1 From 1bb64d753432ddfd38694b04ff18d14679e08246 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 30 Dec 2011 00:07:17 +0100 Subject: fixed last commit --- src/engine/server/server.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 9bb36b74..d29b640b 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1511,16 +1511,21 @@ void CServer::ConLogout(IConsole::IResult *pResult, void *pUser) { CServer *pServer = (CServer *)pUser; - CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); - Msg.AddInt(0); //authed - Msg.AddInt(0); //cmdlist - pServer->SendMsgEx(&Msg, MSGFLAG_VITAL, pServer->m_RconClientID, true); - - pServer->m_aClients[pServer->m_RconClientID].m_Authed = AUTHED_NO; - pServer->SendRconLine(pServer->m_RconClientID, "You've logged out"); - char aBuf[32]; - str_format(aBuf, sizeof(aBuf), "ClientID=%d logged out", pServer->m_RconClientID); - pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + if(pServer->m_RconClientID >= 0 && pServer->m_RconClientID < MAX_CLIENTS && + pServer->m_aClients[pServer->m_RconClientID].m_State != CServer::CClient::STATE_EMPTY) + { + CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); + Msg.AddInt(0); //authed + Msg.AddInt(0); //cmdlist + pServer->SendMsgEx(&Msg, MSGFLAG_VITAL, pServer->m_RconClientID, true); + + pServer->m_aClients[pServer->m_RconClientID].m_Authed = AUTHED_NO; + pServer->m_aClients[pServer->m_RconClientID].m_pRconCmdToSend = 0; + pServer->SendRconLine(pServer->m_RconClientID, "Logout successful."); + char aBuf[32]; + str_format(aBuf, sizeof(aBuf), "ClientID=%d logged out", pServer->m_RconClientID); + pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + } } void CServer::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) @@ -1583,7 +1588,7 @@ void CServer::RegisterCommands() Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, "Kick player with specified id for any reason"); Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "List players"); Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "Shut down"); - Console()->Register("logout", "", CFGFLAG_SERVER, ConLogout, this, "Logs you out of Rcon"); + Console()->Register("logout", "", CFGFLAG_SERVER, ConLogout, this, "Logout of rcon"); Console()->Register("record", "?s", CFGFLAG_SERVER|CFGFLAG_STORE, ConRecord, this, "Record to a file"); Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, "Stop recording"); -- cgit 1.4.1 From ec4bb9453785ba78abc0b42614269fc4d8b11cc6 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 30 Dec 2011 19:12:31 +0100 Subject: added logout command for econ --- src/engine/console.h | 1 + src/engine/server/server.cpp | 4 ++-- src/engine/shared/config.h | 3 ++- src/engine/shared/config_variables.h | 12 ++++++------ src/engine/shared/console.cpp | 14 ++++++++++++-- src/engine/shared/console.h | 3 ++- src/engine/shared/econ.cpp | 19 ++++++++++++++++--- src/engine/shared/econ.h | 2 ++ 8 files changed, 43 insertions(+), 15 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/console.h b/src/engine/console.h index 0abf4ad2..8951d2d1 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -78,6 +78,7 @@ public: virtual bool LineIsValid(const char *pStr) = 0; virtual void ExecuteLine(const char *Sptr) = 0; + virtual void ExecuteLineFlag(const char *Sptr, int FlasgMask) = 0; virtual void ExecuteLineStroked(int Stroke, const char *pStr) = 0; virtual void ExecuteFile(const char *pFilename) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index d29b640b..14824cd7 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -961,7 +961,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) m_RconClientID = ClientID; m_RconAuthLevel = m_aClients[ClientID].m_Authed; Console()->SetAccessLevel(m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD); - Console()->ExecuteLine(pCmd); + Console()->ExecuteLineFlag(pCmd, CFGFLAG_SERVER); Console()->SetAccessLevel(IConsole::ACCESS_LEVEL_ADMIN); m_RconClientID = -1; m_RconAuthLevel = AUTHED_ADMIN; @@ -1649,7 +1649,7 @@ int main(int argc, const char **argv) // ignore_convention IEngine *pEngine = CreateEngine("Teeworlds"); IEngineMap *pEngineMap = CreateEngineMap(); IGameServer *pGameServer = CreateGameServer(); - IConsole *pConsole = CreateConsole(CFGFLAG_SERVER); + IConsole *pConsole = CreateConsole(CFGFLAG_SERVER|CFGFLAG_ECON); IEngineMasterServer *pEngineMasterServer = CreateEngineMasterServer(); IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); // ignore_convention IConfig *pConfig = CreateConfig(); diff --git a/src/engine/shared/config.h b/src/engine/shared/config.h index ed89daa2..c6d8437f 100644 --- a/src/engine/shared/config.h +++ b/src/engine/shared/config.h @@ -20,7 +20,8 @@ enum CFGFLAG_CLIENT=2, CFGFLAG_SERVER=4, CFGFLAG_STORE=8, - CFGFLAG_MASTER=16 + CFGFLAG_MASTER=16, + CFGFLAG_ECON=32, }; #endif diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index c812063a..f0dfc570 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -89,12 +89,12 @@ MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "Th MACRO_CONFIG_INT(SvAutoDemoRecord, sv_auto_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos") MACRO_CONFIG_INT(SvAutoDemoMax, sv_auto_demo_max, 10, 0, 1000, CFGFLAG_SERVER, "Maximum number of automatically recorded demos (0 = no limit)") -MACRO_CONFIG_STR(EcBindaddr, ec_bindaddr, 128, "localhost", CFGFLAG_SERVER, "Address to bind the external console to. Anything but 'localhost' is dangerous") -MACRO_CONFIG_INT(EcPort, ec_port, 0, 0, 0, CFGFLAG_SERVER, "Port to use for the external console") -MACRO_CONFIG_STR(EcPassword, ec_password, 32, "", CFGFLAG_SERVER, "External console password") -MACRO_CONFIG_INT(EcBantime, ec_bantime, 0, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if econ authentication fails. 0 just closes the connection") -MACRO_CONFIG_INT(EcAuthTimeout, ec_auth_timeout, 30, 1, 120, CFGFLAG_SERVER, "Time in seconds before the the econ authentification times out") -MACRO_CONFIG_INT(EcOutputLevel, ec_output_level, 1, 0, 2, CFGFLAG_SERVER, "Adjusts the amount of information in the external console") +MACRO_CONFIG_STR(EcBindaddr, ec_bindaddr, 128, "localhost", CFGFLAG_ECON, "Address to bind the external console to. Anything but 'localhost' is dangerous") +MACRO_CONFIG_INT(EcPort, ec_port, 0, 0, 0, CFGFLAG_ECON, "Port to use for the external console") +MACRO_CONFIG_STR(EcPassword, ec_password, 32, "", CFGFLAG_ECON, "External console password") +MACRO_CONFIG_INT(EcBantime, ec_bantime, 0, 0, 1440, CFGFLAG_ECON, "The time a client gets banned if econ authentication fails. 0 just closes the connection") +MACRO_CONFIG_INT(EcAuthTimeout, ec_auth_timeout, 30, 1, 120, CFGFLAG_ECON, "Time in seconds before the the econ authentification times out") +MACRO_CONFIG_INT(EcOutputLevel, ec_output_level, 1, 0, 2, CFGFLAG_ECON, "Adjusts the amount of information in the external console") MACRO_CONFIG_INT(Debug, debug, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Debug mode") MACRO_CONFIG_INT(DbgStress, dbg_stress, 0, 0, 0, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Stress systems") diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 1b98a158..31c2281d 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -12,6 +12,8 @@ #include "console.h" #include "linereader.h" +// todo: rework this + const char *CConsole::CResult::GetString(unsigned Index) { if (Index < 0 || Index >= m_NumArgs) @@ -374,6 +376,14 @@ void CConsole::ExecuteLine(const char *pStr) CConsole::ExecuteLineStroked(0, pStr); // then release it } +void CConsole::ExecuteLineFlag(const char *pStr, int FlagMask) +{ + int Temp = m_FlagMask; + m_FlagMask = FlagMask; + ExecuteLine(pStr); + m_FlagMask = Temp; +} + void CConsole::ExecuteFile(const char *pFilename) { @@ -633,7 +643,7 @@ void CConsole::ParseArguments(int NumArgs, const char **ppArguments) void CConsole::AddCommandSorted(CCommand *pCommand) { - if(!m_pFirstCommand || str_comp(pCommand->m_pName, m_pFirstCommand->m_pName) < 0) + if(!m_pFirstCommand || str_comp(pCommand->m_pName, m_pFirstCommand->m_pName) <= 0) { if(m_pFirstCommand && m_pFirstCommand->m_pNext) pCommand->m_pNext = m_pFirstCommand; @@ -645,7 +655,7 @@ void CConsole::AddCommandSorted(CCommand *pCommand) { for(CCommand *p = m_pFirstCommand; p; p = p->m_pNext) { - if(!p->m_pNext || str_comp(pCommand->m_pName, p->m_pNext->m_pName) < 0) + if(!p->m_pNext || str_comp(pCommand->m_pName, p->m_pNext->m_pName) <= 0) { pCommand->m_pNext = p->m_pNext; p->m_pNext = pCommand; diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 6989c696..61798c37 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -156,7 +156,7 @@ class CConsole : public IConsole public: CConsole(int FlagMask); - virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int Flagmask) const; + virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int FlagMask) const; virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp); virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser); @@ -170,6 +170,7 @@ public: virtual bool LineIsValid(const char *pStr); virtual void ExecuteLine(const char *pStr); + virtual void ExecuteLineFlag(const char *pStr, int FlagMask); virtual void ExecuteFile(const char *pFilename); virtual int RegisterPrintCallback(int OutputLevel, FPrintCallback pfnPrintCallback, void *pUserData); diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp index 3eaf7aac..e85bbd9b 100644 --- a/src/engine/shared/econ.cpp +++ b/src/engine/shared/econ.cpp @@ -52,6 +52,14 @@ void CEcon::ConchainEconOutputLevelUpdate(IConsole::IResult *pResult, void *pUse } } +void CEcon::ConLogout(IConsole::IResult *pResult, void *pUserData) +{ + CEcon *pThis = static_cast(pUserData); + + if(pThis->m_UserClientID >= 0 && pThis->m_UserClientID < NET_MAX_CONSOLE_CLIENTS && pThis->m_aClients[pThis->m_UserClientID].m_State != CClient::STATE_EMPTY) + pThis->m_NetConsole.Drop(pThis->m_UserClientID, "Logout"); +} + void CEcon::Init(IConsole *pConsole, CNetBan *pNetBan) { m_pConsole = pConsole; @@ -60,6 +68,7 @@ void CEcon::Init(IConsole *pConsole, CNetBan *pNetBan) m_aClients[i].m_State = CClient::STATE_EMPTY; m_Ready = false; + m_UserClientID = -1; if(g_Config.m_EcPort == 0 || g_Config.m_EcPassword[0] == 0) return; @@ -84,6 +93,8 @@ void CEcon::Init(IConsole *pConsole, CNetBan *pNetBan) Console()->Chain("ec_output_level", ConchainEconOutputLevelUpdate, this); m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_EcOutputLevel, SendLineCB, this); + + Console()->Register("logout", "", CFGFLAG_ECON, ConLogout, this, "Logout of econ"); } else Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,"econ", "couldn't open socket. port might already be in use"); @@ -115,9 +126,9 @@ void CEcon::Update() else { m_aClients[ClientID].m_AuthTries++; - char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "Wrong password %d/%d.", m_aClients[ClientID].m_AuthTries, MAX_AUTH_TRIES); - m_NetConsole.Send(ClientID, aBuf); + char aMsg[128]; + str_format(aMsg, sizeof(aMsg), "Wrong password %d/%d.", m_aClients[ClientID].m_AuthTries, MAX_AUTH_TRIES); + m_NetConsole.Send(ClientID, aMsg); if(m_aClients[ClientID].m_AuthTries >= MAX_AUTH_TRIES) { if(!g_Config.m_EcBantime) @@ -132,7 +143,9 @@ void CEcon::Update() char aFormatted[256]; str_format(aFormatted, sizeof(aBuf), "cid=%d cmd='%s'", ClientID, aBuf); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aFormatted); + m_UserClientID = ClientID; Console()->ExecuteLine(aBuf); + m_UserClientID = -1; } } diff --git a/src/engine/shared/econ.h b/src/engine/shared/econ.h index ed7d929b..197c7a00 100644 --- a/src/engine/shared/econ.h +++ b/src/engine/shared/econ.h @@ -32,9 +32,11 @@ class CEcon bool m_Ready; int m_PrintCBIndex; + int m_UserClientID; static void SendLineCB(const char *pLine, void *pUserData); static void ConchainEconOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + static void ConLogout(IConsole::IResult *pResult, void *pUserData); static int NewClientCallback(int ClientID, void *pUser); static int DelClientCallback(int ClientID, const char *pReason, void *pUser); -- cgit 1.4.1 From 8052ddf0ff3fcf09cb1679e20b0dc8818f05cf91 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 30 Dec 2011 19:35:57 +0100 Subject: fixed compiling --- src/engine/server/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 14824cd7..04896022 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -208,7 +208,7 @@ int CServerBan::BanExt(T *pBanPool, const typename T::CDataType *pData, int Seco return Result; // drop banned clients - T::CDataType Data = *pData; + typename T::CDataType Data = *pData; for(int i = 0; i < MAX_CLIENTS; ++i) { if(Server()->m_aClients[i].m_State == CServer::CClient::STATE_EMPTY) -- cgit 1.4.1 From c975390195eed17c615bbebfab981a2394dec424 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 31 Dec 2011 12:11:48 +0100 Subject: made vote ban check if the ip matches an authed player --- src/engine/server.h | 6 ++++++ src/engine/server/server.cpp | 23 +++++++++++++++++++++-- src/engine/server/server.h | 1 + src/game/server/gamecontext.cpp | 3 ++- 4 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/server.h b/src/engine/server.h index f3c9ca7c..2e4a2f25 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -55,6 +55,12 @@ public: virtual void SnapSetStaticsize(int ItemType, int Size) = 0; + enum + { + RCON_CID_SERV=-1, + RCON_CID_VOTE=-2, + }; + virtual void SetRconCID(int ClientID) = 0; virtual bool IsAuthed(int ClientID) = 0; virtual void Kick(int ClientID, const char *pReason) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 04896022..de84ad35 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -202,6 +202,20 @@ int CServerBan::BanExt(T *pBanPool, const typename T::CDataType *pData, int Seco } } } + else if(Server()->m_RconClientID == IServer::RCON_CID_VOTE) + { + for(int i = 0; i < MAX_CLIENTS; ++i) + { + if(Server()->m_aClients[i].m_State == CServer::CClient::STATE_EMPTY) + continue; + + if(Server()->m_aClients[i].m_Authed != CServer::AUTHED_NO && NetMatch(pData, Server()->m_NetServer.ClientAddr(i))) + { + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "net_ban", "ban error (command denied)"); + return -1; + } + } + } int Result = Ban(pBanPool, pData, Seconds, pReason); if(Result != 0) @@ -290,7 +304,7 @@ CServer::CServer() : m_DemoRecorder(&m_SnapshotDelta) m_MapReload = 0; - m_RconClientID = -1; + m_RconClientID = IServer::RCON_CID_SERV; m_RconAuthLevel = AUTHED_ADMIN; Init(); @@ -431,6 +445,11 @@ int CServer::Init() return 0; } +void CServer::SetRconCID(int ClientID) +{ + m_RconClientID = ClientID; +} + bool CServer::IsAuthed(int ClientID) { return m_aClients[ClientID].m_Authed; @@ -963,7 +982,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) Console()->SetAccessLevel(m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD); Console()->ExecuteLineFlag(pCmd, CFGFLAG_SERVER); Console()->SetAccessLevel(IConsole::ACCESS_LEVEL_ADMIN); - m_RconClientID = -1; + m_RconClientID = IServer::RCON_CID_SERV; m_RconAuthLevel = AUTHED_ADMIN; } } diff --git a/src/engine/server/server.h b/src/engine/server/server.h index fe79a3da..e32f6733 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -177,6 +177,7 @@ public: int Init(); + void SetRconCID(int ClientID); bool IsAuthed(int ClientID); int GetClientInfo(int ClientID, CClientInfo *pInfo); void GetClientAddr(int ClientID, char *pAddrStr, int Size); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 0cd8e801..1f163983 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -481,7 +481,9 @@ void CGameContext::OnTick() if(m_VoteEnforce == VOTE_ENFORCE_YES) { + Server()->SetRconCID(IServer::RCON_CID_VOTE); Console()->ExecuteLine(m_aVoteCommand); + Server()->SetRconCID(IServer::RCON_CID_SERV); EndVote(); SendChat(-1, CGameContext::CHAT_ALL, "Vote passed"); @@ -737,7 +739,6 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) char aAddrStr[NETADDR_MAXSTRSIZE] = {0}; Server()->GetClientAddr(KickID, aAddrStr, sizeof(aAddrStr)); str_format(aCmd, sizeof(aCmd), "ban %s %d Banned by vote", aAddrStr, g_Config.m_SvVoteKickBantime); - Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aCmd); } } else if(str_comp_nocase(pMsg->m_Type, "spectate") == 0) -- cgit 1.4.1 From 29738552a69e5b74410f2667e81243593cc26233 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 6 Jan 2012 19:17:14 +0100 Subject: made bindaddr config work for client and master too. Closes #909 --- src/engine/client/client.cpp | 7 ++++-- src/engine/server/server.cpp | 2 +- src/engine/shared/config_variables.h | 2 +- src/mastersrv/mastersrv.cpp | 48 ++++++++++++++++++++++-------------- 4 files changed, 36 insertions(+), 23 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index a9c86060..34923f28 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1738,8 +1738,11 @@ void CClient::Run() // open socket { NETADDR BindAddr; - mem_zero(&BindAddr, sizeof(BindAddr)); - BindAddr.type = NETTYPE_ALL; + if(g_Config.m_Bindaddr[0] == 0 || net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) != 0) + { + mem_zero(&BindAddr, sizeof(BindAddr)); + BindAddr.type = NETTYPE_ALL; + } if(!m_NetClient.Open(BindAddr, 0)) { dbg_msg("client", "couldn't start network"); diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index de84ad35..6e63f747 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1271,7 +1271,7 @@ int CServer::Run() // start server NETADDR BindAddr; - if(g_Config.m_SvBindaddr[0] && net_host_lookup(g_Config.m_SvBindaddr, &BindAddr, NETTYPE_ALL) == 0) + if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0) { // sweet! BindAddr.port = g_Config.m_SvPort; diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index d92073d7..f76e69c8 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -77,7 +77,7 @@ MACRO_CONFIG_INT(GfxThreaded, gfx_threaded, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT MACRO_CONFIG_INT(InpMousesens, inp_mousesens, 100, 5, 100000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Mouse sensitivity") MACRO_CONFIG_STR(SvName, sv_name, 128, "unnamed server", CFGFLAG_SERVER, "Server name") -MACRO_CONFIG_STR(SvBindaddr, sv_bindaddr, 128, "", CFGFLAG_SERVER, "Address to bind the server to") +MACRO_CONFIG_STR(Bindaddr, bindaddr, 128, "", CFGFLAG_CLIENT|CFGFLAG_SERVER|CFGFLAG_MASTER, "Address to bind the client/server to") MACRO_CONFIG_INT(SvPort, sv_port, 8303, 0, 0, CFGFLAG_SERVER, "Port to use for the server") MACRO_CONFIG_INT(SvExternalPort, sv_external_port, 0, 0, 0, CFGFLAG_SERVER, "External port to report to the master servers") MACRO_CONFIG_STR(SvMap, sv_map, 128, "dm1", CFGFLAG_SERVER, "Map to use on the server") diff --git a/src/mastersrv/mastersrv.cpp b/src/mastersrv/mastersrv.cpp index 632a524c..c6099139 100644 --- a/src/mastersrv/mastersrv.cpp +++ b/src/mastersrv/mastersrv.cpp @@ -2,6 +2,7 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include +#include #include #include #include @@ -326,16 +327,40 @@ int main(int argc, const char **argv) // ignore_convention dbg_logger_stdout(); net_init(); - mem_zero(&BindAddr, sizeof(BindAddr)); - BindAddr.type = NETTYPE_ALL; - BindAddr.port = MASTERSERVER_PORT; + mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT)); + mem_copy(m_CountDataLegacy.m_Header, SERVERBROWSE_COUNT_LEGACY, sizeof(SERVERBROWSE_COUNT_LEGACY)); + + IKernel *pKernel = IKernel::Create(); + IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); + IConfig *pConfig = CreateConfig(); + m_pConsole = CreateConsole(CFGFLAG_MASTER); + + bool RegisterFail = !pKernel->RegisterInterface(pStorage); + RegisterFail |= !pKernel->RegisterInterface(m_pConsole); + RegisterFail |= !pKernel->RegisterInterface(pConfig); + + if(RegisterFail) + return -1; + + pConfig->Init(); + m_NetBan.Init(m_pConsole, pStorage); + if(argc > 1) // ignore_convention + m_pConsole->ParseArguments(argc-1, &argv[1]); // ignore_convention + + if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0) + BindAddr.port = MASTERSERVER_PORT; + else + { + mem_zero(&BindAddr, sizeof(BindAddr)); + BindAddr.type = NETTYPE_ALL; + BindAddr.port = MASTERSERVER_PORT; + } if(!m_NetOp.Open(BindAddr, 0)) { dbg_msg("mastersrv", "couldn't start network (op)"); return -1; } - BindAddr.port = MASTERSERVER_PORT+1; if(!m_NetChecker.Open(BindAddr, 0)) { @@ -343,21 +368,6 @@ int main(int argc, const char **argv) // ignore_convention return -1; } - mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT)); - mem_copy(m_CountDataLegacy.m_Header, SERVERBROWSE_COUNT_LEGACY, sizeof(SERVERBROWSE_COUNT_LEGACY)); - - IKernel *pKernel = IKernel::Create(); - IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); - - m_pConsole = CreateConsole(CFGFLAG_MASTER); - m_NetBan.Init(m_pConsole, pStorage); - - bool RegisterFail = !pKernel->RegisterInterface(pStorage); - RegisterFail |= !pKernel->RegisterInterface(m_pConsole); - - if(RegisterFail) - return -1; - dbg_msg("mastersrv", "started"); while(1) -- cgit 1.4.1 From 4fde2cf7f2353c045bcf483e7958d785dac3be64 Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 9 Jan 2012 00:49:20 +0100 Subject: add tuning to demo. Closes #899 --- src/engine/server.h | 1 + src/engine/server/server.cpp | 5 +++++ src/engine/server/server.h | 1 + src/game/client/gameclient.cpp | 9 +++++++++ src/game/server/gamecontext.cpp | 11 +++++++++++ 5 files changed, 27 insertions(+) (limited to 'src/engine/server') diff --git a/src/engine/server.h b/src/engine/server.h index 2e4a2f25..5036b654 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -65,6 +65,7 @@ public: virtual void Kick(int ClientID, const char *pReason) = 0; virtual void DemoRecorder_HandleAutoStart() = 0; + virtual bool DemoRecorder_IsRecording() = 0; }; class IGameServer : public IInterface diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 6e63f747..c15cc96e 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1500,6 +1500,11 @@ void CServer::DemoRecorder_HandleAutoStart() } } +bool CServer::DemoRecorder_IsRecording() +{ + return m_DemoRecorder.IsRecording(); +} + void CServer::ConRecord(IConsole::IResult *pResult, void *pUser) { CServer* pServer = (CServer *)pUser; diff --git a/src/engine/server/server.h b/src/engine/server/server.h index e32f6733..696b472d 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -170,6 +170,7 @@ public: void Kick(int ClientID, const char *pReason); void DemoRecorder_HandleAutoStart(); + bool DemoRecorder_IsRecording(); //int Tick() int64 TickStartTime(int Tick); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 6e94c830..467a55a0 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -893,6 +893,15 @@ void CGameClient::OnNewSnapshot() m_ServerMode = SERVERMODE_PUREMOD; } + // add tuning to demo + if(DemoRecorder()->IsRecording() && mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) != 0) + { + CMsgPacker Msg(NETMSGTYPE_SV_TUNEPARAMS); + int *pParams = (int *)&m_Tuning; + for(unsigned i = 0; i < sizeof(m_Tuning)/sizeof(int); i++) + Msg.AddInt(pParams[i]); + Client()->SendMsg(&Msg, MSGFLAG_RECORD|MSGFLAG_NOSEND); + } } void CGameClient::OnPredict() diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 868ac593..fdd78f60 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1511,6 +1511,17 @@ void CGameContext::OnShutdown() void CGameContext::OnSnap(int ClientID) { + // add tuning to demo + CTuningParams StandardTuning; + if(ClientID == -1 && Server()->DemoRecorder_IsRecording() && mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) != 0) + { + CMsgPacker Msg(NETMSGTYPE_SV_TUNEPARAMS); + int *pParams = (int *)&m_Tuning; + for(unsigned i = 0; i < sizeof(m_Tuning)/sizeof(int); i++) + Msg.AddInt(pParams[i]); + Server()->SendMsg(&Msg, MSGFLAG_RECORD|MSGFLAG_NOSEND, ClientID); + } + m_World.Snap(ClientID); m_pController->Snap(ClientID); m_Events.Snap(ClientID); -- cgit 1.4.1 From 40735202143f8c4d2a539d1d81362c0c22e9324b Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 9 Jan 2012 01:38:45 +0100 Subject: cleaned up content folder creation. Closes #845 --- src/engine/client/client.cpp | 2 +- src/engine/server/server.cpp | 2 +- src/engine/shared/storage.cpp | 21 ++++++++++++--------- src/engine/storage.h | 8 ++++++-- src/mastersrv/mastersrv.cpp | 2 +- src/tools/map_resave.cpp | 4 ++-- src/tools/map_version.cpp | 2 +- 7 files changed, 24 insertions(+), 17 deletions(-) (limited to 'src/engine/server') diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 8faf1e41..0e380e40 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2272,7 +2272,7 @@ int main(int argc, const char **argv) // ignore_convention // create the components IEngine *pEngine = CreateEngine("Teeworlds"); IConsole *pConsole = CreateConsole(CFGFLAG_CLIENT); - IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); // ignore_convention + IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_CLIENT, argc, argv); // ignore_convention IConfig *pConfig = CreateConfig(); IEngineSound *pEngineSound = CreateEngineSound(); IEngineInput *pEngineInput = CreateEngineInput(); diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index c15cc96e..5fa265f2 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1675,7 +1675,7 @@ int main(int argc, const char **argv) // ignore_convention IGameServer *pGameServer = CreateGameServer(); IConsole *pConsole = CreateConsole(CFGFLAG_SERVER|CFGFLAG_ECON); IEngineMasterServer *pEngineMasterServer = CreateEngineMasterServer(); - IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); // ignore_convention + IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_SERVER, argc, argv); // ignore_convention IConfig *pConfig = CreateConfig(); pServer->InitRegister(&pServer->m_NetServer, pEngineMasterServer, pConsole); diff --git a/src/engine/shared/storage.cpp b/src/engine/shared/storage.cpp index c1888188..a9ccdc49 100644 --- a/src/engine/shared/storage.cpp +++ b/src/engine/shared/storage.cpp @@ -30,7 +30,7 @@ public: m_aUserdir[0] = 0; } - int Init(const char *pApplicationName, int NumArgs, const char **ppArguments) + int Init(const char *pApplicationName, int StorageType, int NumArgs, const char **ppArguments) { // get userdir fs_storage_path(pApplicationName, m_aUserdir, sizeof(m_aUserdir)); @@ -52,14 +52,17 @@ public: } // add save directories - if(m_NumPaths && (!m_aaStoragePaths[TYPE_SAVE][0] || !fs_makedir(m_aaStoragePaths[TYPE_SAVE]))) + if(StorageType != STORAGETYPE_BASIC && m_NumPaths && (!m_aaStoragePaths[TYPE_SAVE][0] || !fs_makedir(m_aaStoragePaths[TYPE_SAVE]))) { char aPath[MAX_PATH_LENGTH]; - fs_makedir(GetPath(TYPE_SAVE, "screenshots", aPath, sizeof(aPath))); - fs_makedir(GetPath(TYPE_SAVE, "screenshots/auto", aPath, sizeof(aPath))); - fs_makedir(GetPath(TYPE_SAVE, "maps", aPath, sizeof(aPath))); + if(StorageType == STORAGETYPE_CLIENT) + { + fs_makedir(GetPath(TYPE_SAVE, "screenshots", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "screenshots/auto", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "maps", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "downloadedmaps", aPath, sizeof(aPath))); + } fs_makedir(GetPath(TYPE_SAVE, "dumps", aPath, sizeof(aPath))); - fs_makedir(GetPath(TYPE_SAVE, "downloadedmaps", aPath, sizeof(aPath))); fs_makedir(GetPath(TYPE_SAVE, "demos", aPath, sizeof(aPath))); fs_makedir(GetPath(TYPE_SAVE, "demos/auto", aPath, sizeof(aPath))); } @@ -389,10 +392,10 @@ public: GetPath(Type, pDir, pBuffer, BufferSize); } - static IStorage *Create(const char *pApplicationName, int NumArgs, const char **ppArguments) + static IStorage *Create(const char *pApplicationName, int StorageType, int NumArgs, const char **ppArguments) { CStorage *p = new CStorage(); - if(p && p->Init(pApplicationName, NumArgs, ppArguments)) + if(p && p->Init(pApplicationName, StorageType, NumArgs, ppArguments)) { dbg_msg("storage", "initialisation failed"); delete p; @@ -402,4 +405,4 @@ public: } }; -IStorage *CreateStorage(const char *pApplicationName, int NumArgs, const char **ppArguments) { return CStorage::Create(pApplicationName, NumArgs, ppArguments); } +IStorage *CreateStorage(const char *pApplicationName, int StorageType, int NumArgs, const char **ppArguments) { return CStorage::Create(pApplicationName, StorageType, NumArgs, ppArguments); } diff --git a/src/engine/storage.h b/src/engine/storage.h index bcfb9ce2..25aa8b3e 100644 --- a/src/engine/storage.h +++ b/src/engine/storage.h @@ -12,7 +12,11 @@ public: enum { TYPE_SAVE = 0, - TYPE_ALL = -1 + TYPE_ALL = -1, + + STORAGETYPE_BASIC = 0, + STORAGETYPE_SERVER, + STORAGETYPE_CLIENT, }; virtual void ListDirectory(int Type, const char *pPath, FS_LISTDIR_CALLBACK pfnCallback, void *pUser) = 0; @@ -24,7 +28,7 @@ public: virtual void GetCompletePath(int Type, const char *pDir, char *pBuffer, unsigned BufferSize) = 0; }; -extern IStorage *CreateStorage(const char *pApplicationName, int NumArgs, const char **ppArguments); +extern IStorage *CreateStorage(const char *pApplicationName, int StorageType, int NumArgs, const char **ppArguments); #endif diff --git a/src/mastersrv/mastersrv.cpp b/src/mastersrv/mastersrv.cpp index c6099139..c88a9e78 100644 --- a/src/mastersrv/mastersrv.cpp +++ b/src/mastersrv/mastersrv.cpp @@ -331,7 +331,7 @@ int main(int argc, const char **argv) // ignore_convention mem_copy(m_CountDataLegacy.m_Header, SERVERBROWSE_COUNT_LEGACY, sizeof(SERVERBROWSE_COUNT_LEGACY)); IKernel *pKernel = IKernel::Create(); - IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); + IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); IConfig *pConfig = CreateConfig(); m_pConsole = CreateConsole(CFGFLAG_MASTER); diff --git a/src/tools/map_resave.cpp b/src/tools/map_resave.cpp index a536f021..0a624b0f 100644 --- a/src/tools/map_resave.cpp +++ b/src/tools/map_resave.cpp @@ -6,7 +6,7 @@ int main(int argc, const char **argv) { - IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); + IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); int Index, ID = 0, Type = 0, Size; void *pPtr; char aFileName[1024]; @@ -16,7 +16,7 @@ int main(int argc, const char **argv) if(!pStorage || argc != 3) return -1; - str_format(aFileName, sizeof(aFileName), "maps/%s", argv[2]); + str_format(aFileName, sizeof(aFileName), "%s", argv[2]); if(!DataFile.Open(pStorage, argv[1], IStorage::TYPE_ALL)) return -1; diff --git a/src/tools/map_version.cpp b/src/tools/map_version.cpp index 4acc51e0..8d8c59e3 100644 --- a/src/tools/map_version.cpp +++ b/src/tools/map_version.cpp @@ -44,7 +44,7 @@ int MaplistCallback(const char *pName, int IsDir, int DirType, void *pUser) int main(int argc, const char **argv) // ignore_convention { IKernel *pKernel = IKernel::Create(); - s_pStorage = CreateStorage("Teeworlds", argc, argv); + s_pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); s_pEngineMap = CreateEngineMap(); bool RegisterFail = !pKernel->RegisterInterface(s_pStorage); -- cgit 1.4.1 From 00f580cb91130370a99c0d080974450f2377e62a Mon Sep 17 00:00:00 2001 From: fisted Date: Sat, 28 Jan 2012 23:54:04 +0100 Subject: tell what port might be in use, if we cannot bind --- src/engine/server/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/engine/server') diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 5fa265f2..a231d1e8 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1285,7 +1285,7 @@ int CServer::Run() if(!m_NetServer.Open(BindAddr, &m_ServerBan, g_Config.m_SvMaxClients, g_Config.m_SvMaxClientsPerIP, 0)) { - dbg_msg("server", "couldn't open socket. port might already be in use"); + dbg_msg("server", "couldn't open socket. port %d might already be in use", g_Config.m_SvPort); return -1; } -- cgit 1.4.1