From 9be652170bce766ac87907595fc4831317bd4d34 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 2 Jul 2011 20:09:24 +0200 Subject: added update for dutch translation by Syntax Error --- data/languages/czech.txt | 1 + data/languages/dutch.txt | 28 ++++++++++++++-------------- data/languages/swedish.txt | 37 ++++++++++++++++++++----------------- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/data/languages/czech.txt b/data/languages/czech.txt index 7f26b274..83d657a1 100644 --- a/data/languages/czech.txt +++ b/data/languages/czech.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes diff --git a/data/languages/dutch.txt b/data/languages/dutch.txt index 978ff608..4375f784 100644 --- a/data/languages/dutch.txt +++ b/data/languages/dutch.txt @@ -62,7 +62,7 @@ Are you sure that you want to remove the player from your friends list? == Weet je zeker dat je deze speler uit je vriendenlijst wilt verwijderen? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Omdat dit de eerste keer is dat je het spel opstart, moet je een nicknaam kiezen. Doe dat hieronder. Het is aanbevolen om de instellingen te controleren, voordat je een spel start. +== Omdat dit de eerste keer is dat je het spel opstart, moet je een bijnaam kiezen. Doe dat hieronder. Het is aanbevolen om de instellingen te controleren voordat je een spel start. Automatically record demos == Automatisch demo's opnemen @@ -145,6 +145,9 @@ Delete demo Demo details == Demo details +Demofile: %s +== Demobestand: %s + Demos == Demo's @@ -350,7 +353,7 @@ Next weapon == Volgend wapen Nickname -== Nicknaam +== Bijnaam No == Nee @@ -394,6 +397,9 @@ Play background music Player == Speler +Player country: +== Speler land: + Player options == Speler opties @@ -428,10 +434,10 @@ Record demo == Neem demo op Red team -== Rood +== Rode team Red team wins! -== Rood wint! +== Rode team wint! Refresh == Vernieuwen @@ -562,6 +568,9 @@ Standard map Stop record == Stop met opnemen +Strict gametype filter +== Strikt speltype filter + Sudden Death == Sudden Death @@ -590,7 +599,7 @@ There's an unsaved map in the editor, you might want to save it before you quit == Er is een onopgeslagen kaart in de editor, misschien wil je deze opslaan voordat je stopt. Time limit -== Tijdlimiet +== Tijdslimiet Time limit: %d min == Tijdslimiet: %d minuten @@ -666,14 +675,5 @@ no limit ##### needs translation ##### -Demofile: %s -== - -Player country: -== - -Strict gametype filter -== - ##### old translations ##### diff --git a/data/languages/swedish.txt b/data/languages/swedish.txt index 38bde2f2..7f48d95d 100644 --- a/data/languages/swedish.txt +++ b/data/languages/swedish.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes @@ -144,6 +145,9 @@ Delete demo Demo details == Demoinformation +Demofile: %s +== Demofil: %s + Demos == Demon @@ -387,9 +391,15 @@ Pistol Play == Spela +Play background music +== Aktivera bakgrundsmusik + Player == Spelare +Player country: +== Land + Player options == Spelaralternativ @@ -537,6 +547,12 @@ Sound volume Spectate == Åskåda +Spectate next +== Se på nästa + +Spectate previous +== Se på föregående + Spectator mode == Åskådarläge @@ -552,6 +568,9 @@ Standard map Stop record == Sluta spela in +Strict gametype filter +== Strikt speltypsfilter + Sudden Death == Plötslig död @@ -654,23 +673,7 @@ Your skin no limit == Ingen gräns -Demofile: %s -== Demofil: %s - -Play background music -== Aktivera bakgrundsmusik - -Player country: -== Land - -Spectate next -== Se på nästa - -Spectate previous -== Se på föregående - -Strict gametype filter -== Strikt speltypsfilter +##### needs translation ##### ##### old translations ##### -- cgit 1.4.1 From 7b6e75f4516eb8cc3f04506d6077137e37b2f4cf Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 2 Jul 2011 20:24:44 +0200 Subject: added for Slovak translation by LimiT --- data/languages/slovak.txt | 80 +++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/data/languages/slovak.txt b/data/languages/slovak.txt index 57f96e25..48816234 100644 --- a/data/languages/slovak.txt +++ b/data/languages/slovak.txt @@ -14,16 +14,16 @@ == Zostáva %ds %i minute left -== Zostáva %i minúta +== Zostávajúce minúty: %i %i minutes left -== Zostáva %i minút +== Zostávajúce minúty: %i %i second left -== Zostáva %i sekunda +== Zostávajúce sekundy: %i %i seconds left -== Zostáva %i sekúnd +== Zostávajúce sekundy: %i %s wins! == %s vyhráva! @@ -62,7 +62,7 @@ Are you sure that you want to remove the player from your friends list? == Ste si istí, že chcete tohto hráča odstrániť zo zoznamu priateľov? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Vitajte v hre TeeWorlds. Pred tým, ako sa pripojíte na herný server, odporúčame nastaviť si hru podľa svojich požiadavkov. Napíšte do políčka nižšie meno pre Vášho tee a pokračujte kliknutím na tlačítko. +== Vitajte v hre TeeWorlds. Predtým, ako sa pripojíte na herný server, odporúčame nastaviť si hru podľa svojich požiadavkov. Napíšte do políčka nižšie meno pre Vášho tee a pokračujte kliknutím na tlačítko. Automatically record demos == Automaticky nahrávať záznamy @@ -116,7 +116,7 @@ Controls == Ovládanie Count players only -== Rátať len hráčov +== Nepočítať divákov Country == Krajina @@ -145,6 +145,9 @@ Delete demo Demo details == Detaily nahrávky +Demofile: %s +== Nahrávka: %s + Demos == Záznamy @@ -254,7 +257,7 @@ Hue == Hue Info -== Informácie +== Info Internet == Internet @@ -320,7 +323,7 @@ Move left == Pohyb vľavo Move player to spectators -== Presunúť hráča do skupiny divákov +== Poslať hráča pozorovať Move right == Pohyb vpravo @@ -365,7 +368,7 @@ No servers match your filter criteria == Žiadny server nezodpovedá zadaným kritériám Ok -== Ok +== OK Open == Otvoriť @@ -388,9 +391,15 @@ Pistol Play == Prehrať +Play background music +== Prehrať hudbu na pozadí + Player == Hráč +Player country: +== Filter krajín: + Player options == Nastavenia hráča @@ -407,7 +416,7 @@ Quality Textures == Kvalitné textúry Quick search: -== Rýchle hľadanie: +== Hľadanie: Quit == Ukončiť @@ -473,13 +482,13 @@ Score == Skóre Score board -== Prehľad skóre +== Tabuľka výsledkov Score limit == Limit skóre Scoreboard -== Prehľad skóre +== Tabuľka výsledkov Screenshot == Screenshot @@ -527,7 +536,7 @@ Skins == Skiny Sound -== Zvuky +== Zvuk Sound error == Zvuková chyba @@ -538,6 +547,12 @@ Sound volume Spectate == Pozorovať +Spectate next +== Pozorovať ďalšieho + +Spectate previous +== Pozorovať predch. + Spectator mode == Mód diváka @@ -545,14 +560,17 @@ Spectators == Diváci Standard gametype -== Štandartný herný typ +== Štandardný herný typ Standard map -== Štandartná mapa +== Štandardná mapa Stop record == Nenahrávať +Strict gametype filter +== Striktný filter módov + Sudden Death == Rýchla Smrť @@ -560,7 +578,7 @@ Switch weapon on pickup == Nastavovať zdvíhanú zbraň ako aktuálnu Team -== Tým +== Týmu Team chat == Týmový chat @@ -575,10 +593,10 @@ The audio device couldn't be initialised. == Zvukové zariadenie nemohlo byť inicializované. The server is running a non-standard tuning on a pure game type. -== Na serveri je nastavený neštandartný tuning. +== Server používa neštandardné nastavenia na základnom hernom móde. There's an unsaved map in the editor, you might want to save it before you quit the game. -== V editore máte neuloženú mapu, mali by ste si ju uložiť predtým než skončíte hru. +== V editore máte neuloženú mapu, možno si ju chcete pred skončením hry uložiť. Time limit == Časový limit @@ -602,7 +620,7 @@ Unable to delete the demo == Nemôžem vymazať záznam Unable to rename the demo -== Nedá sa premenovať nahrávka +== Nahrávka sa nedá premenovať Use sounds == Povoliť zvuky @@ -626,10 +644,10 @@ Vote description: == Popis hlasu: Vote no -== Hlasovať proti +== Nie Vote yes -== Hlasovať pre +== Áno Voting == Hlasovanie @@ -638,7 +656,7 @@ Warmup == Rozohrávka Weapon -== Zbraň +== Zbrane Welcome to Teeworlds == Vitajte v hre Teeworlds! @@ -657,23 +675,5 @@ no limit ##### needs translation ##### -Demofile: %s -== - -Play background music -== - -Player country: -== - -Spectate next -== - -Spectate previous -== - -Strict gametype filter -== - ##### old translations ##### -- cgit 1.4.1 From 6b4080aee8b19fe6d3aba5b716d6287d51e369fd Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 3 Jul 2011 00:23:26 +0200 Subject: added update for Portuguese translation by Slinack --- data/languages/portuguese.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index e129a23b..fd484551 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -397,6 +397,9 @@ Play background music Player == Jogador +Player country: +== País do jogador: + Player options == Opções do jogador @@ -563,7 +566,7 @@ Standard map == Mapa padrão Stop record -== Parar de gravar +== Parar a gravação Strict gametype filter == Tipo de jogo exato @@ -672,8 +675,5 @@ no limit ##### needs translation ##### -Player country: -== - ##### old translations ##### -- cgit 1.4.1 From 7648ba30246ca8a692c27328145225535b8f300e Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 3 Jul 2011 00:36:07 +0200 Subject: added a different mouse sens for menus/editor --- src/game/client/components/emoticon.cpp | 1 + src/game/client/components/menus.cpp | 1 + src/game/client/components/spectator.cpp | 1 + src/game/client/ui.cpp | 7 +++++++ src/game/client/ui.h | 1 + src/game/editor/editor.cpp | 1 + src/game/variables.h | 1 + 7 files changed, 13 insertions(+) diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp index 741a604f..bedfaafb 100644 --- a/src/game/client/components/emoticon.cpp +++ b/src/game/client/components/emoticon.cpp @@ -54,6 +54,7 @@ bool CEmoticon::OnMouseMove(float x, float y) if(!m_Active) return false; + UI()->ConvertMouseMove(&x, &y); m_SelectorMouse += vec2(x,y); return true; } diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 9826d863..4f3d2da7 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1348,6 +1348,7 @@ bool CMenus::OnMouseMove(float x, float y) if(!m_MenuActive) return false; + UI()->ConvertMouseMove(&x, &y); m_MousePos.x += x; m_MousePos.y += y; if(m_MousePos.x < 0) m_MousePos.x = 0; diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index e98df118..c69a7669 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -139,6 +139,7 @@ bool CSpectator::OnMouseMove(float x, float y) if(!m_Active) return false; + UI()->ConvertMouseMove(&x, &y); m_SelectorMouse += vec2(x,y); return true; } diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp index 2161bc77..00a30c15 100644 --- a/src/game/client/ui.cpp +++ b/src/game/client/ui.cpp @@ -53,6 +53,13 @@ int CUI::MouseInside(const CUIRect *r) return 0; } +void CUI::ConvertMouseMove(float *x, float *y) +{ + float Fac = (float)(g_Config.m_UiMousesens)/g_Config.m_InpMousesens; + *x = *x*Fac; + *y = *y*Fac; +} + CUIRect *CUI::Screen() { float Aspect = Graphics()->ScreenAspect(); diff --git a/src/game/client/ui.h b/src/game/client/ui.h index 017abf7c..7cd78d6f 100644 --- a/src/game/client/ui.h +++ b/src/game/client/ui.h @@ -79,6 +79,7 @@ public: const void *LastActiveItem() const { return m_pLastActiveItem; } int MouseInside(const CUIRect *pRect); + void ConvertMouseMove(float *x, float *y); CUIRect *Screen(); void ClipEnable(const CUIRect *pRect); diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 8c186085..bc00c4a2 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -3337,6 +3337,7 @@ void CEditor::UpdateAndRender() float rx, ry; { Input()->MouseRelative(&rx, &ry); + UI()->ConvertMouseMove(&rx, &ry); m_MouseDeltaX = rx; m_MouseDeltaY = ry; diff --git a/src/game/variables.h b/src/game/variables.h index 3af299cf..d6cf5ac5 100644 --- a/src/game/variables.h +++ b/src/game/variables.h @@ -45,6 +45,7 @@ MACRO_CONFIG_INT(UiPage, ui_page, 5, 0, 10, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Interf MACRO_CONFIG_INT(UiToolboxPage, ui_toolbox_page, 0, 0, 2, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Toolbox page") MACRO_CONFIG_STR(UiServerAddress, ui_server_address, 64, "localhost:8303", CFGFLAG_CLIENT|CFGFLAG_SAVE, "Interface server address") MACRO_CONFIG_INT(UiScale, ui_scale, 100, 50, 150, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Interface scale") +MACRO_CONFIG_INT(UiMousesens, ui_mousesens, 100, 5, 100000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Mouse sensitivity for menus/editor") MACRO_CONFIG_INT(UiColorHue, ui_color_hue, 160, 0, 255, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Interface color hue") MACRO_CONFIG_INT(UiColorSat, ui_color_sat, 70, 0, 255, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Interface color saturation") -- cgit 1.4.1 From b153003b0b6f08b55fc46645ff522234fe351e67 Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 4 Jul 2011 18:30:24 +0200 Subject: fixed dm wincheck --- src/game/server/gamecontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index f0facb8c..fd574d85 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -662,7 +662,7 @@ bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam) void IGameController::DoWincheck() { - if(m_GameOverTick == -1 && !m_Warmup) + if(m_GameOverTick == -1 && !m_Warmup && !GameServer()->m_World.m_ResetRequested) { if(IsTeamplay()) { -- cgit 1.4.1 From 7f546488eedbfc1c97503326afe85ac590045d86 Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 4 Jul 2011 23:31:22 +0200 Subject: added update for Bosnian translation by *** --- data/languages/bosnian.txt | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/data/languages/bosnian.txt b/data/languages/bosnian.txt index d5c9ccd8..4888db6a 100644 --- a/data/languages/bosnian.txt +++ b/data/languages/bosnian.txt @@ -145,6 +145,9 @@ Delete demo Demo details == Podaci o demo-snimku +Demofile: %s +== Demo-snimak: %s + Demos == Demo @@ -388,9 +391,15 @@ Pistol Play == Pogledaj +Play background music +== Pozadinska muzika + Player == Igrač +Player country: +== Država + Player options == Postavke igrača @@ -538,6 +547,12 @@ Sound volume Spectate == Posmatraj +Spectate next +== Posmatraj narednog + +Spectate previous +== Posmatraj prethodnog + Spectator mode == Posmatrački mod @@ -553,6 +568,9 @@ Standard map Stop record == Prekini snimanje +Strict gametype filter +== Striktan filter tipa igre + Sudden Death == Iznenadna smrt @@ -657,23 +675,5 @@ no limit ##### needs translation ##### -Demofile: %s -== - -Play background music -== - -Player country: -== - -Spectate next -== - -Spectate previous -== - -Strict gametype filter -== - ##### old translations ##### -- cgit 1.4.1 From 4869d0ed3586d55efc5037c7d96364c709c1b5d5 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 18:04:09 +0200 Subject: added a SDL dll built with the latest 1.2 source which can handle accented character input. Closes #745 --- other/sdl/vc2005libs/SDL.dll | Bin 324096 -> 243712 bytes other/sdl/vc2005libs/SDL.lib | Bin 42702 -> 42698 bytes other/sdl/vc2005libs/SDLmain.lib | Bin 8264 -> 24330 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/other/sdl/vc2005libs/SDL.dll b/other/sdl/vc2005libs/SDL.dll index 628cdfcf..9663f9b0 100644 Binary files a/other/sdl/vc2005libs/SDL.dll and b/other/sdl/vc2005libs/SDL.dll differ diff --git a/other/sdl/vc2005libs/SDL.lib b/other/sdl/vc2005libs/SDL.lib index 5b3f17c5..e2d84a0a 100644 Binary files a/other/sdl/vc2005libs/SDL.lib and b/other/sdl/vc2005libs/SDL.lib differ diff --git a/other/sdl/vc2005libs/SDLmain.lib b/other/sdl/vc2005libs/SDLmain.lib index 945b9ad8..6cc1c5a8 100644 Binary files a/other/sdl/vc2005libs/SDLmain.lib and b/other/sdl/vc2005libs/SDLmain.lib differ -- cgit 1.4.1 From 5008b5f8a52a2692e5396cd67bf3ad13332e074b Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 18:31:04 +0200 Subject: Added update for Finnish translation by ziltoide --- data/languages/finnish.txt | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/data/languages/finnish.txt b/data/languages/finnish.txt index 8aab046f..77ce6cf7 100644 --- a/data/languages/finnish.txt +++ b/data/languages/finnish.txt @@ -145,6 +145,9 @@ Delete demo Demo details == Demon tiedot +Demofile: %s +== Demotiedosto: %s + Demos == Demot @@ -388,9 +391,15 @@ Pistol Play == Toista +Play background music +== Soita taustamusiikki + Player == Pelaaja +Player country: +== Pelaajan maa: + Player options == Pelaajavalinnat @@ -509,7 +518,7 @@ Show chat == Näytä chatti Show friends only -== Näytä ystävät +== Näytä vain ystävät Show ingame HUD == Näytä peli-HUD @@ -538,6 +547,12 @@ Sound volume Spectate == Katso +Spectate next +== Katso seuraavaa + +Spectate previous +== Katso edellistä + Spectator mode == Katsojatila @@ -553,6 +568,9 @@ Standard map Stop record == Lopeta nauhoit. +Strict gametype filter +== Tarkka pelityyppisuodin + Sudden Death == Äkkikuolema @@ -657,23 +675,5 @@ no limit ##### needs translation ##### -Demofile: %s -== - -Play background music -== - -Player country: -== - -Spectate next -== - -Spectate previous -== - -Strict gametype filter -== - ##### old translations ##### -- cgit 1.4.1 From 1ae474689d564e1feba9924842f05e06600d83a1 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 21:54:10 +0200 Subject: added moderator support for the remote console. #518 --- src/engine/console.h | 7 +- src/engine/server/server.cpp | 58 +++++++++++++--- src/engine/server/server.h | 8 +++ src/engine/shared/config_variables.h | 3 +- src/engine/shared/console.cpp | 129 +++++++++++++++++++++++++++-------- src/engine/shared/console.h | 6 ++ 6 files changed, 172 insertions(+), 39 deletions(-) diff --git a/src/engine/console.h b/src/engine/console.h index f8ec67b0..e650ac47 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -14,7 +14,10 @@ public: { OUTPUT_LEVEL_STANDARD=0, OUTPUT_LEVEL_ADDINFO, - OUTPUT_LEVEL_DEBUG + OUTPUT_LEVEL_DEBUG, + + ACCESS_LEVEL_ADMIN=0, + ACCESS_LEVEL_MOD, }; // TODO: rework this interface to reduce the amount of virtual calls @@ -62,6 +65,8 @@ public: virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData) = 0; virtual void Print(int Level, const char *pFrom, const char *pStr) = 0; + + virtual void SetAccessLevel(int AccessLevel) = 0; }; extern IConsole *CreateConsole(int FlagMask); diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 0e43e73f..14467b2b 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1,6 +1,7 @@ /* (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 @@ -181,6 +182,7 @@ CServer::CServer() : m_DemoRecorder(&m_SnapshotDelta) m_MapReload = 0; m_RconClientID = -1; + m_RconAuthLevel = AUTHED_ADMIN; Init(); } @@ -280,6 +282,11 @@ void CServer::Kick(int ClientID, const char *pReason) Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "you can't kick yourself"); return; } + else if(m_aClients[ClientID].m_Authed > m_RconAuthLevel) + { + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "kick command denied"); + return; + } m_NetServer.Drop(ClientID, pReason); } @@ -571,7 +578,7 @@ int CServer::NewClientCallback(int ClientID, void *pUser) pThis->m_aClients[ClientID].m_aName[0] = 0; pThis->m_aClients[ClientID].m_aClan[0] = 0; pThis->m_aClients[ClientID].m_Country = -1; - pThis->m_aClients[ClientID].m_Authed = 0; + pThis->m_aClients[ClientID].m_Authed = AUTHED_NO; pThis->m_aClients[ClientID].m_AuthTries = 0; pThis->m_aClients[ClientID].Reset(); return 0; @@ -596,7 +603,7 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) pThis->m_aClients[ClientID].m_aName[0] = 0; pThis->m_aClients[ClientID].m_aClan[0] = 0; pThis->m_aClients[ClientID].m_Country = -1; - pThis->m_aClients[ClientID].m_Authed = 0; + pThis->m_aClients[ClientID].m_Authed = AUTHED_NO; pThis->m_aClients[ClientID].m_AuthTries = 0; pThis->m_aClients[ClientID].m_Snapshots.PurgeAll(); return 0; @@ -635,7 +642,7 @@ void CServer::SendRconLineAuthed(const char *pLine, void *pUser) for(i = 0; i < MAX_CLIENTS; i++) { - if(pThis->m_aClients[i].m_State != CClient::STATE_EMPTY && pThis->m_aClients[i].m_Authed) + if(pThis->m_aClients[i].m_State != CClient::STATE_EMPTY && pThis->m_aClients[i].m_Authed >= pThis->m_RconAuthLevel) pThis->SendRconLine(i, pLine); } @@ -813,8 +820,12 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) str_format(aBuf, sizeof(aBuf), "ClientID=%d rcon='%s'", ClientID, pCmd); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); 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()->SetAccessLevel(IConsole::ACCESS_LEVEL_ADMIN); m_RconClientID = -1; + m_RconAuthLevel = AUTHED_ADMIN; } } else if(Msg == NETMSG_RCON_AUTH) @@ -825,9 +836,9 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) if(Unpacker.Error() == 0) { - if(g_Config.m_SvRconPassword[0] == 0) + if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0]) { - SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password to enable the remote console."); + SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password to enable the remote console."); } else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0) { @@ -835,10 +846,22 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) Msg.AddInt(1); SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); - m_aClients[ClientID].m_Authed = 1; - SendRconLine(ClientID, "Authentication successful. Remote console access granted."); + m_aClients[ClientID].m_Authed = AUTHED_ADMIN; + SendRconLine(ClientID, "Admin authentication successful. Full remote console access granted."); + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (admin)", ClientID); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + } + else if(str_comp(pPw, g_Config.m_SvRconModPassword) == 0) + { + CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); + Msg.AddInt(1); + SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); + + m_aClients[ClientID].m_Authed = AUTHED_MOD; + SendRconLine(ClientID, "Moderator authentication successful. Limited remote console access granted."); char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "ClientID=%d authed", ClientID); + str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (moderator)", ClientID); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); } else if(g_Config.m_SvRconMaxTries) @@ -1308,6 +1331,20 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser) 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); } @@ -1325,6 +1362,11 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser) 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); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index be36a856..72c82d4d 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -49,6 +49,13 @@ public: class IConsole *Console() { return m_pConsole; } class IStorage *Storage() { return m_pStorage; } + enum + { + AUTHED_NO=0, + AUTHED_MOD, + AUTHED_ADMIN, + }; + class CClient { public: @@ -110,6 +117,7 @@ public: int m_RunServer; int m_MapReload; int m_RconClientID; + int m_RconAuthLevel; int64 m_Lastheartbeat; //static NETADDR4 master_server; diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 31a8128a..213ebf26 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -82,7 +82,8 @@ MACRO_CONFIG_INT(SvMaxClients, sv_max_clients, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER MACRO_CONFIG_INT(SvMaxClientsPerIP, sv_max_clients_per_ip, 4, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients with the same IP that can connect to the server") MACRO_CONFIG_INT(SvHighBandwidth, sv_high_bandwidth, 0, 0, 1, CFGFLAG_SERVER, "Use high bandwidth mode. Doubles the bandwidth required for the server. LAN use only") MACRO_CONFIG_INT(SvRegister, sv_register, 1, 0, 1, CFGFLAG_SERVER, "Register server with master server for public listing") -MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password") +MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password (full access)") +MACRO_CONFIG_STR(SvRconModPassword, sv_rcon_mod_password, 32, "", CFGFLAG_SERVER, "Remote console password for moderators (limited access)") MACRO_CONFIG_INT(SvRconMaxTries, sv_rcon_max_tries, 3, 0, 100, CFGFLAG_SERVER, "Maximum number of tries for remote console authentication") MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if remote console authentication fails. 0 makes it just use kick") diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 3fd73543..588abd61 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -1,11 +1,15 @@ /* (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 "console.h" +#include + #include "config.h" +#include "console.h" #include "linereader.h" const char *CConsole::CResult::GetString(unsigned Index) @@ -247,38 +251,47 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) if(ParseStart(&Result, pStr, (pEnd-pStr) + 1) != 0) return; - if (!*Result.m_pCommand) + if(!*Result.m_pCommand) return; CCommand *pCommand = FindCommand(Result.m_pCommand, m_FlagMask); if(pCommand) { - int IsStrokeCommand = 0; - if(Result.m_pCommand[0] == '+') - { - // insert the stroke direction token - Result.AddArgument(m_paStrokeStr[Stroke]); - IsStrokeCommand = 1; - } - - if(Stroke || IsStrokeCommand) + if(pCommand->m_AccessLevel >= m_AccessLevel) { - if(ParseArgs(&Result, pCommand->m_pParams)) + int IsStrokeCommand = 0; + if(Result.m_pCommand[0] == '+') { - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "Invalid arguments... Usage: %s %s", pCommand->m_pName, pCommand->m_pParams); - Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); + // insert the stroke direction token + Result.AddArgument(m_paStrokeStr[Stroke]); + IsStrokeCommand = 1; } - else if(m_StoreCommands && pCommand->m_Flags&CFGFLAG_STORE) + + if(Stroke || IsStrokeCommand) { - m_ExecutionQueue.AddEntry(); - m_ExecutionQueue.m_pLast->m_pfnCommandCallback = pCommand->m_pfnCallback; - m_ExecutionQueue.m_pLast->m_pCommandUserData = pCommand->m_pUserData; - m_ExecutionQueue.m_pLast->m_Result = Result; + if(ParseArgs(&Result, pCommand->m_pParams)) + { + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "Invalid arguments... Usage: %s %s", pCommand->m_pName, pCommand->m_pParams); + Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); + } + else if(m_StoreCommands && pCommand->m_Flags&CFGFLAG_STORE) + { + m_ExecutionQueue.AddEntry(); + m_ExecutionQueue.m_pLast->m_pfnCommandCallback = pCommand->m_pfnCallback; + m_ExecutionQueue.m_pLast->m_pCommandUserData = pCommand->m_pUserData; + m_ExecutionQueue.m_pLast->m_Result = Result; + } + else + pCommand->m_pfnCallback(&Result, pCommand->m_pUserData); } - else - pCommand->m_pfnCallback(&Result, pCommand->m_pUserData); + } + else if(Stroke) + { + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "Access for command %s denied.", Result.m_pCommand); + Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); } } else if(Stroke) @@ -294,8 +307,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) void CConsole::PossibleCommands(const char *pStr, int FlagMask, FPossibleCallback pfnCallback, void *pUser) { - CCommand *pCommand; - for(pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) + for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) { if(pCommand->m_Flags&FlagMask) { @@ -307,8 +319,7 @@ void CConsole::PossibleCommands(const char *pStr, int FlagMask, FPossibleCallbac CConsole::CCommand *CConsole::FindCommand(const char *pName, int FlagMask) { - CCommand *pCommand; - for (pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) + for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) { if(pCommand->m_Flags&FlagMask) { @@ -383,6 +394,62 @@ void CConsole::Con_Exec(IResult *pResult, void *pUserData) ((CConsole*)pUserData)->ExecuteFile(pResult->GetString(0)); } +void CConsole::ConModCommandAccess(IResult *pResult, void *pUser) +{ + CConsole* pConsole = static_cast(pUser); + char aBuf[128]; + CCommand *pCommand = pConsole->FindCommand(pResult->GetString(0), CFGFLAG_SERVER); + if(pCommand) + { + if(pResult->NumArguments() == 2) + { + pCommand->m_AccessLevel = clamp(pResult->GetInteger(1), (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_MOD)); + str_format(aBuf, sizeof(aBuf), "moderator access for '%s' is now %s", pResult->GetString(0), pCommand->m_AccessLevel ? "enabled" : "disabled"); + } + else + str_format(aBuf, sizeof(aBuf), "moderator access for '%s' is %s", pResult->GetString(0), pCommand->m_AccessLevel ? "enabled" : "disabled"); + } + else + str_format(aBuf, sizeof(aBuf), "No such command: '%s'.", pResult->GetString(0)); + + pConsole->Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); +} + +void CConsole::ConModCommandStatus(IResult *pResult, void *pUser) +{ + CConsole* pConsole = static_cast(pUser); + char aBuf[240]; + mem_zero(aBuf, sizeof(aBuf)); + int Used = 0; + + for(CCommand *pCommand = pConsole->m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) + { + if(pCommand->m_Flags&pConsole->m_FlagMask && pCommand->m_AccessLevel == ACCESS_LEVEL_MOD) + { + int Length = str_length(pCommand->m_pName); + if(Used + Length + 2 < (int)(sizeof(aBuf))) + { + if(Used > 0) + { + Used += 2; + str_append(aBuf, ", ", sizeof(aBuf)); + } + str_append(aBuf, pCommand->m_pName, sizeof(aBuf)); + Used += Length; + } + else + { + pConsole->Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); + mem_zero(aBuf, sizeof(aBuf)); + str_copy(aBuf, pCommand->m_pName, sizeof(aBuf)); + Used = Length; + } + } + } + if(Used > 0) + pConsole->Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); +} + struct CIntVariableData { IConsole *m_pConsole; @@ -463,6 +530,7 @@ static void StrVariableCommand(IConsole::IResult *pResult, void *pUserData) CConsole::CConsole(int FlagMask) { m_FlagMask = FlagMask; + m_AccessLevel = ACCESS_LEVEL_ADMIN; m_StoreCommands = true; m_paStrokeStr[0] = "0"; m_paStrokeStr[1] = "1"; @@ -478,6 +546,9 @@ CConsole::CConsole(int FlagMask) Register("echo", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, Con_Echo, this, "Echo the text"); Register("exec", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, Con_Exec, this, "Execute the specified file"); + Register("mod_command", "s?i", CFGFLAG_SERVER, ConModCommandAccess, this, "Specify command accessibility for moderators"); + Register("mod_status", "", CFGFLAG_SERVER, ConModCommandStatus, this, "List all commands which are accessible for moderators"); + // TODO: this should disappear #define MACRO_CONFIG_INT(Name,ScriptName,Def,Min,Max,Flags,Desc) \ { \ @@ -524,14 +595,14 @@ void CConsole::ParseArguments(int NumArgs, const char **ppArguments) void CConsole::Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) { - CCommand *pCommand = (CCommand *)mem_alloc(sizeof(CCommand), sizeof(void*)); + CCommand *pCommand = new(mem_alloc(sizeof(CCommand), sizeof(void*))) CCommand; pCommand->m_pfnCallback = pfnFunc; pCommand->m_pUserData = pUser; pCommand->m_pHelp = pHelp; pCommand->m_pName = pName; pCommand->m_pParams = pParams; pCommand->m_Flags = Flags; - + pCommand->m_AccessLevel = ACCESS_LEVEL_ADMIN; pCommand->m_pNext = m_pFirstCommand; m_pFirstCommand = pCommand; diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 0866d8e3..14c48581 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -13,6 +13,7 @@ class CConsole : public IConsole public: CCommand *m_pNext; int m_Flags; + int m_AccessLevel; FCommandCallback m_pfnCallback; void *m_pUserData; }; @@ -41,10 +42,13 @@ class CConsole : public IConsole CExecFile *m_pFirstExec; class IStorage *m_pStorage; + int m_AccessLevel; static void Con_Chain(IResult *pResult, void *pUserData); static void Con_Echo(IResult *pResult, void *pUserData); static void Con_Exec(IResult *pResult, void *pUserData); + static void ConModCommandAccess(IResult *pResult, void *pUser); + static void ConModCommandStatus(IConsole::IResult *pResult, void *pUser); void ExecuteFileRecurse(const char *pFilename); void ExecuteLineStroked(int Stroke, const char *pStr); @@ -153,6 +157,8 @@ public: virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData); virtual void Print(int Level, const char *pFrom, const char *pStr); + + void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_MOD)); } }; #endif -- cgit 1.4.1 From ab1f7d6f95346c7bf86dfbdfa015c7e850097918 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 22:58:54 +0200 Subject: clamped information flow when moving as spectator in free-view. Closes #551 --- src/game/server/player.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 1f822524..3e4d7be5 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -60,6 +60,9 @@ void CPlayer::Tick() } } + if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW) + m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -5000.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f)); + if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick()) m_Spawning = true; @@ -193,9 +196,6 @@ void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput) if(!m_pCharacter && m_Team != TEAM_SPECTATORS && (NewInput->m_Fire&1)) m_Spawning = true; - if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW) - m_ViewPos = vec2(NewInput->m_TargetX, NewInput->m_TargetY); - // check for activity if(NewInput->m_Direction || m_LatestActivity.m_TargetX != NewInput->m_TargetX || m_LatestActivity.m_TargetY != NewInput->m_TargetY || NewInput->m_Jump || -- cgit 1.4.1 From ac9c3b8f7f26b3b1676345ddca82272fd31fc0ff Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 23:15:24 +0200 Subject: made the dropped flag sign blink faster the last 5 seconds to indicate that it's about to return. Closes #631 --- src/game/client/components/hud.cpp | 4 +++- src/game/client/gameclient.cpp | 16 ++++++++++++++++ src/game/client/gameclient.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 58fc75b9..11343912 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -108,7 +108,9 @@ void CHud::RenderScoreHud() if(GameFlags&GAMEFLAG_FLAGS) { - if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick()/10)&1))) + 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))) { // draw flag Graphics()->BlendNormal(); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index a3c2dfc2..4618d7dc 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -341,6 +341,8 @@ void CGameClient::OnReset() m_All.m_paComponents[i]->OnReset(); m_DemoSpecID = SPEC_FREEVIEW; + m_FlagDropTick[TEAM_RED] = 0; + m_FlagDropTick[TEAM_BLUE] = 0; } @@ -783,6 +785,20 @@ void CGameClient::OnNewSnapshot() { m_Snap.m_pGameDataObj = (const CNetObj_GameData *)pData; m_Snap.m_GameDataSnapID = Item.m_ID; + if(m_Snap.m_pGameDataObj->m_FlagCarrierRed == FLAG_TAKEN) + { + if(m_FlagDropTick[TEAM_RED] == 0) + m_FlagDropTick[TEAM_RED] = Client()->GameTick(); + } + else if(m_FlagDropTick[TEAM_RED] != 0) + m_FlagDropTick[TEAM_RED] = 0; + if(m_Snap.m_pGameDataObj->m_FlagCarrierBlue == FLAG_TAKEN) + { + if(m_FlagDropTick[TEAM_BLUE] == 0) + m_FlagDropTick[TEAM_BLUE] = Client()->GameTick(); + } + else if(m_FlagDropTick[TEAM_BLUE] != 0) + m_FlagDropTick[TEAM_BLUE] = 0; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 859e1e7b..4783f8b4 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -89,6 +89,7 @@ public: bool m_SuppressEvents; bool m_NewTick; bool m_NewPredictedTick; + int m_FlagDropTick[2]; // TODO: move this CTuningParams m_Tuning; -- cgit 1.4.1 From 20fbe2f92c57811bb9f20b084f052339f3f678d0 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 23:23:33 +0200 Subject: fixed that player friends are marked as online in the friends list if they match a clan friend --- src/game/client/components/menus_browser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index f2926f87..8501c67d 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -252,7 +252,8 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) (!m_lFriends[f].m_pFriendInfo->m_aName[0] || NameHash == m_lFriends[f].m_pFriendInfo->m_NameHash)) { m_lFriends[f].m_NumFound++; - break; + if(m_lFriends[f].m_pFriendInfo->m_aName[0]) + break; } } } -- cgit 1.4.1 From e18390fea86352a98c377781d97bee1a40deae57 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 5 Jul 2011 23:32:32 +0200 Subject: fixed that client resets tuning. Closes #746 --- src/game/client/gameclient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 4618d7dc..7b6b1192 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -343,6 +343,7 @@ void CGameClient::OnReset() m_DemoSpecID = SPEC_FREEVIEW; m_FlagDropTick[TEAM_RED] = 0; m_FlagDropTick[TEAM_BLUE] = 0; + m_Tuning = CTuningParams(); } -- cgit 1.4.1 From ba2dbd841615878027ae7313b4ac124103231bcb Mon Sep 17 00:00:00 2001 From: Nicolae Crefelean Date: Mon, 4 Jul 2011 17:19:15 -0700 Subject: Edited data/languages/romanian.txt via GitHub --- data/languages/romanian.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/languages/romanian.txt b/data/languages/romanian.txt index 41bc3774..35a479e7 100644 --- a/data/languages/romanian.txt +++ b/data/languages/romanian.txt @@ -1,4 +1,3 @@ - ##### translated strings ##### %d Bytes @@ -332,7 +331,7 @@ Movement == Mișcare Mute when not active -== Mută la inactivate +== Opreşte sunetul la inactivate Name == Nume -- cgit 1.4.1 From 83d8422c4cf3ad2b04b75c7478c92f91c1f8a307 Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 6 Jul 2011 18:20:46 +0200 Subject: added "fixed tcp and added ipv6 tcp support" by SushiTee --- src/base/system.c | 111 +++++++++++++++++++++++++++++++++++------------------- src/base/system.h | 12 +++--- 2 files changed, 78 insertions(+), 45 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 01f0b398..551b3f1b 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -823,8 +823,6 @@ static int priv_net_close_all_sockets(NETSOCKET sock) static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, int sockaddrlen) { int sock, e; - unsigned long mode = 1; - int broadcast = 1; /* create socket */ sock = socket(domain, type, 0); @@ -852,16 +850,6 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i return -1; } - /* set non-blocking */ -#if defined(CONF_FAMILY_WINDOWS) - ioctlsocket(sock, FIONBIO, &mode); -#else - ioctl(sock, FIONBIO, &mode); -#endif - - /* set boardcast */ - setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)); - /* return the newly created socket */ return sock; } @@ -870,6 +858,7 @@ NETSOCKET net_udp_create(NETADDR bindaddr) { NETSOCKET sock = invalid_socket; NETADDR tmpbindaddr = bindaddr; + int broadcast = 1; if(bindaddr.type&NETTYPE_IPV4) { @@ -885,6 +874,12 @@ NETSOCKET net_udp_create(NETADDR bindaddr) sock.type |= NETTYPE_IPV4; sock.ipv4sock = socket; } + + /* set non-blocking */ + net_set_non_blocking(sock); + + /* set boardcast */ + setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)); } if(bindaddr.type&NETTYPE_IPV6) @@ -901,6 +896,12 @@ NETSOCKET net_udp_create(NETADDR bindaddr) sock.type |= NETTYPE_IPV6; sock.ipv6sock = socket; } + + /* set non-blocking */ + net_set_non_blocking(sock); + + /* set boardcast */ + setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)); } /* return */ @@ -1010,32 +1011,48 @@ int net_udp_close(NETSOCKET sock) return priv_net_close_all_sockets(sock); } -// TODO: make TCP stuff work again -NETSOCKET net_tcp_create(const NETADDR *a) +NETSOCKET net_tcp_create(NETADDR bindaddr) { - /* TODO: IPv6 support */ NETSOCKET sock = invalid_socket; + NETADDR tmpbindaddr = bindaddr; - if(a->type&NETTYPE_IPV4) + if(bindaddr.type&NETTYPE_IPV4) { struct sockaddr_in addr; + int socket = -1; - /* create socket */ - sock.type |= NETTYPE_IPV4; - sock.ipv4sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock.ipv4sock < 0) - return invalid_socket; + /* bind, we should check for error */ + tmpbindaddr.type = NETTYPE_IPV4; + netaddr_to_sockaddr_in(&tmpbindaddr, &addr); + socket = priv_net_create_socket(AF_INET, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr)); + if(socket >= 0) + { + sock.type |= NETTYPE_IPV4; + sock.ipv4sock = socket; + } + } + + if(bindaddr.type&NETTYPE_IPV6) + { + struct sockaddr_in6 addr; + int socket = -1; /* bind, we should check for error */ - netaddr_to_sockaddr_in(a, &addr); - bind(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr)); + tmpbindaddr.type = NETTYPE_IPV6; + netaddr_to_sockaddr_in6(&tmpbindaddr, &addr); + socket = priv_net_create_socket(AF_INET6, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr)); + if(socket >= 0) + { + sock.type |= NETTYPE_IPV6; + sock.ipv6sock = socket; + } } /* return */ return sock; } -int net_tcp_set_non_blocking(NETSOCKET sock) +int net_set_non_blocking(NETSOCKET sock) { unsigned long mode = 1; if(sock.ipv4sock >= 0) @@ -1059,7 +1076,7 @@ int net_tcp_set_non_blocking(NETSOCKET sock) return 0; } -int net_tcp_set_blocking(NETSOCKET sock) +int net_set_blocking(NETSOCKET sock) { unsigned long mode = 0; if(sock.ipv4sock >= 0) @@ -1133,24 +1150,30 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) int net_tcp_connect(NETSOCKET sock, const NETADDR *a) { - /*struct sockaddr addr; - netaddr_to_sockaddr(a, &addr); - return connect(sock, &addr, sizeof(addr)); - */ + if(a->type&NETTYPE_IPV4) + { + struct sockaddr_in addr; + netaddr_to_sockaddr_in(a, &addr); + return connect(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr)); + } + + if(a->type&NETTYPE_IPV6) + { + struct sockaddr_in6 addr; + netaddr_to_sockaddr_in6(a, &addr); + return connect(sock.ipv6sock, (struct sockaddr *)&addr, sizeof(addr)); + } + return 0; } -int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a) +int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr) { - /* struct sockaddr addr; */ int res = 0; - /* - netaddr_to_sockaddr(a, &addr); - net_tcp_set_non_blocking(sock); - res = connect(sock, &addr, sizeof(addr)); - net_tcp_set_blocking(sock); - */ + net_set_non_blocking(sock); + res = net_tcp_connect(sock, &bindaddr); + net_set_blocking(sock); return res; } @@ -1158,14 +1181,24 @@ int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a) int net_tcp_send(NETSOCKET sock, const void *data, int size) { int bytes = 0; - /* bytes = send((int)sock, (const char*)data, size, 0); */ + + if(sock.ipv4sock >= 0) + 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; } int net_tcp_recv(NETSOCKET sock, void *data, int maxsize) { int bytes = 0; - /* bytes = recv((int)sock, (char*)data, maxsize, 0); */ + + if(sock.ipv4sock >= 0) + 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/base/system.h b/src/base/system.h index de579076..aaa5b43f 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -591,7 +591,7 @@ int net_udp_close(NETSOCKET sock); Returns: On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID. */ -NETSOCKET net_tcp_create(const NETADDR *a); +NETSOCKET net_tcp_create(NETADDR bindaddr); /* Function: net_tcp_listen @@ -1094,21 +1094,21 @@ int fs_rename(const char *oldname, const char *newname); DOCTODO: serp */ -int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a); +int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr); /* - Function: net_tcp_set_non_blocking + Function: net_set_non_blocking DOCTODO: serp */ -int net_tcp_set_non_blocking(NETSOCKET sock); +int net_set_non_blocking(NETSOCKET sock); /* - Function: net_tcp_set_non_blocking + Function: net_set_non_blocking DOCTODO: serp */ -int net_tcp_set_blocking(NETSOCKET sock); +int net_set_blocking(NETSOCKET sock); /* Function: net_errno -- cgit 1.4.1 From e37d536fdfd69bbd04b869e381d64840a185b854 Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 7 Jul 2011 01:48:00 +0200 Subject: fixed some NETTYPE usage based on the socket state --- src/engine/client/client.cpp | 8 ++++---- src/engine/client/client.h | 1 - src/engine/server/server.cpp | 2 +- src/engine/shared/network.h | 2 ++ 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 90cb2011..6949c308 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -693,12 +693,12 @@ void CClient::Connect(const char *pAddress) ServerInfoRequest(); - if(net_host_lookup(m_aServerAddressStr, &m_ServerAddress, NETTYPE_ALL) != 0) + if(net_host_lookup(m_aServerAddressStr, &m_ServerAddress, m_NetClient.NetType()) != 0) { char aBufMsg[256]; str_format(aBufMsg, sizeof(aBufMsg), "could not find the address of %s, connecting to localhost", aBuf); m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBufMsg); - net_host_lookup("localhost", &m_ServerAddress, NETTYPE_ALL); + net_host_lookup("localhost", &m_ServerAddress, m_NetClient.NetType()); } m_RconAuthed = 0; @@ -1799,7 +1799,7 @@ void CClient::VersionUpdate() { if(m_VersionInfo.m_State == CVersionInfo::STATE_INIT) { - Engine()->HostLookup(&m_VersionInfo.m_VersionServeraddr, g_Config.m_ClVersionServer, m_BindAddr.type); + Engine()->HostLookup(&m_VersionInfo.m_VersionServeraddr, g_Config.m_ClVersionServer, m_NetClient.NetType()); m_VersionInfo.m_State = CVersionInfo::STATE_START; } else if(m_VersionInfo.m_State == CVersionInfo::STATE_START) @@ -1881,7 +1881,7 @@ void CClient::Run() Input()->Init(); // start refreshing addresses while we load - MasterServer()->RefreshAddresses(m_BindAddr.type); + MasterServer()->RefreshAddresses(m_NetClient.NetType()); // init the editor m_pEditor->Init(); diff --git a/src/engine/client/client.h b/src/engine/client/client.h index ddcd1167..fa0ddaf7 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -118,7 +118,6 @@ class CClient : public IClient, public CDemoPlayer::IListner float m_FrameTimeHigh; int m_Frames; NETADDR m_ServerAddress; - NETADDR m_BindAddr; int m_WindowMustRefocus; int m_SnapCrcErrors; bool m_AutoScreenshotRecycle; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 14467b2b..a707b690 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1246,7 +1246,7 @@ int CServer::Run() } // master server stuff - m_Register.RegisterUpdate(BindAddr.type); + m_Register.RegisterUpdate(m_NetServer.NetType()); PumpNetwork(); diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 425d970a..228ba6dd 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -285,6 +285,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 MaxClients() const { return m_MaxClients; } // @@ -320,6 +321,7 @@ public: int ResetErrorString(); // error and state + int NetType() { return m_Socket.type; } int State(); int GotProblems(); const char *ErrorString(); -- cgit 1.4.1 From 2523d20b40c973723e6983c2361851f62d72813b Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 7 Jul 2011 02:03:04 +0200 Subject: added update for Russian translation by Bananbl4 --- data/languages/romanian.txt | 1 + data/languages/russian.txt | 178 ++++++++++++++++++++++---------------------- 2 files changed, 90 insertions(+), 89 deletions(-) diff --git a/data/languages/romanian.txt b/data/languages/romanian.txt index 35a479e7..e38faadb 100644 --- a/data/languages/romanian.txt +++ b/data/languages/romanian.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes diff --git a/data/languages/russian.txt b/data/languages/russian.txt index 0e4a7c22..2200bb25 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -2,7 +2,7 @@ ##### translated strings ##### %d Bytes -== %d Байтов +== %d байт %d of %d servers, %d players == %d из %d серверов, %d игроков @@ -14,19 +14,19 @@ == осталось %d сек. %i minute left -== %i минута осталась +== осталась %i минута! %i minutes left -== %i минут осталось +== остались %i минут(ы) %i second left -== %i секунда осталась +== осталась %i секунда! %i seconds left -== %i секунд осталось +== остались %i секунд(ы) %s wins! -== %s - победа! +== %s победил! -Page %d- == -Страница %d- @@ -44,10 +44,10 @@ Address == Адрес All -== Все +== Всем Alpha -== Прозрачность +== Прозрачн. Always show name plates == Всегда показывать имена игроков @@ -62,19 +62,19 @@ Are you sure that you want to remove the player from your friends list? == Вы действительно хотите удалить этого игрока из списка друзей? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Вы запустили игру первый раз, пожалуйста, введите ваш никнейм. Мы рекомендуем вам настроить игру. +== Вы запустили игру первый раз, пожалуйста, введите ваш никнейм. Также мы рекомендуем вам настроить игру под себя в меню "Настройки". Automatically record demos == Записывать демо автоматически Automatically take game over screenshot -== Автоматически снимать скриншоты в конце игры +== Автоматически снимать итоги игры Blue team -== Синяя команда +== Синие Blue team wins! -== Синяя команда победила! +== Синие победили! Body == Тело @@ -95,19 +95,19 @@ Client == Клиент Close -== Закрыть +== Выйти Compatible version == Совместимая версия Connect -== Играть +== Подключиться Connecting to -== Соединяемся с +== Подключаемся к Connection Problems... -== Проблемы с соединением... +== Проблемы со связью... Console == Консоль @@ -119,10 +119,10 @@ Count players only == Считать только игроков Country -== Страна +== Флаг Crc: -== Crc-сумма: +== Crc-хэш: Created: == Создан: @@ -134,7 +134,7 @@ Current version: %s == Текущая версия: %s Custom colors -== Произвольный цвет +== Свои цвета Delete == Удалить @@ -143,13 +143,16 @@ Delete demo == Удалить демо Demo details -== Подробности +== Подробнее про это демо + +Demofile: %s +== Демо: %s Demos == Демо Disconnect -== Уйти +== Отключиться Disconnected == Отсоединен @@ -164,7 +167,7 @@ Draw! == Ничья! Dynamic Camera -== Динамичная Камера +== Подвижная камера Emoticon == Эмоции @@ -182,13 +185,13 @@ FSAA samples == FSAA сэмплы Favorite -== Избранное +== Избранный сервер Favorites == Избранное Feet -== Нога +== Ноги Filter == Фильтр @@ -200,13 +203,13 @@ Folder == Папка Force vote -== Форсировать голосование +== Применить Free-View == Свободный просмотр Friends -== Приятели +== Друзья Fullscreen == На весь экран @@ -215,7 +218,7 @@ Game == Игра Game info -== Информация о игре +== Подробности Game over == Игра окончена @@ -233,7 +236,7 @@ Graphics == Графика Grenade -== Граната +== Гранатомёт Hammer == Молоток @@ -242,7 +245,7 @@ Has people playing == Есть игроки на сервере High Detail -== Высокая Детализация +== Высокая детализация Hook == Цепь @@ -260,13 +263,13 @@ Internet == Интернет Invalid Demo -== Невалидное демо +== Нерабочее демо Join blue == К синим Join game -== Войти в игру +== В игру Join red == К красным @@ -302,10 +305,10 @@ Map: == Карта: Max Screenshots -== Максимум Скриншотов +== Максимум скриншотов Max demos -== Максимум Демо +== Максимум демо Maximum ping: == Макс. пинг: @@ -317,19 +320,19 @@ Mouse sens. == Чувст. мыши Move left -== Влево +== Шаг влево Move player to spectators -== Стать наблюдателем +== Сделать наблюдателем Move right -== Вправо +== Шаг вправо Movement == Движение Mute when not active -== Выключить звук когда игра неактивна +== Выключать звук, если игра свёрнута Name == Имя @@ -347,7 +350,7 @@ News == Новости Next weapon -== Следующее оружие +== След. оружие Nickname == Ник @@ -362,16 +365,16 @@ No servers found == Сервера не найдены No servers match your filter criteria -== Нет серверов, подходящих под Ваш фильтр +== Нет серверов, подходящих под ваш фильтр Ok -== Ok +== ОК Open == Открыть Parent Folder -== Корневая папка +== На уровень выше Password == Пароль @@ -386,31 +389,34 @@ Pistol == Пистолет Play -== Воспроизвести +== Запустить Play background music -== Воспроизвести фоновую музыку +== Играть фоновую музыку Player == Игрок +Player country: +== Страна: + Player options -== Настройки игрока +== Настройки игроков Players == Игроки Please balance teams! -== Пожалуйста cбалансируйте команды! +== Пожалуйста, cбалансируйте команды! Prev. weapon == Пред. оружие Quality Textures -== Качественные Текстуры +== Качественные текстуры Quick search: -== Быстрый поиск +== Быстрый поиск: Quit == Выход @@ -419,7 +425,7 @@ Quit anyway? == Всё равно выйти? REC %3d:%02d -== Записано %3d:%02d +== REC %3d:%02d Reason: == Причина: @@ -428,10 +434,10 @@ Record demo == Записать демо Red team -== Красная команда +== Красные Red team wins! -== Красная команда победила! +== Красные победили! Refresh == Обновить @@ -440,7 +446,7 @@ Refreshing master servers == Обновляем мастер-сервера Remote console -== Серверная консоль +== Консоль сервера Remove == Удалить @@ -449,16 +455,16 @@ Remove friend == Удалить из друзей Rename -== Переименовать +== Сменить имя Rename demo -== Переименовать демо +== Сменить имя демо Reset filter == Сбросить фильтр Reset to defaults -== Сбросить на стандартные настройки +== Сбросить настройки Rifle == Лазер @@ -473,16 +479,16 @@ Sat. == Контраст Score -== Очки +== Счёт Score board -== Результат +== Ход игры Score limit -== Лимит на очки +== Лимит счёта Scoreboard -== Результат +== Ход игры Screenshot == Скриншот @@ -491,13 +497,13 @@ Server address: == Адрес сервера: Server details -== Информация о сервере +== Основное Server filter -== Фильтр сервера +== Фильтр Server info -== Инфо +== О сервере Server not full == Сервер не заполнен @@ -512,7 +518,7 @@ Show chat == Показать чат Show friends only -== Показывать друзей +== Только друзья Show ingame HUD == Показывать HUD @@ -524,10 +530,10 @@ Show only supported == Показывать только поддерживаемые Size: -== Размер +== Размер: Skins -== Модели +== Доступные скины Sound == Звук @@ -560,22 +566,25 @@ Standard map == Стандартная карта Stop record -== Остановить запись +== Выкл. запись + +Strict gametype filter +== Строгий фильтр режимов Sudden Death == Внезапная смерть Switch weapon on pickup -== Сменить оружие на подобранное +== Сменять оружие на подобранное Team -== Команда +== Команде Team chat == Командный чат Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s в сети! Скачайте его на www.teeworlds.com! +== Teeworlds %s вышел! Скачайте его на www.teeworlds.com! Texture Compression == Сжатие текстур @@ -587,16 +596,16 @@ The server is running a non-standard tuning on a pure game type. == Этот сервер работает на нестандартных настройках стандартного типа игры. There's an unsaved map in the editor, you might want to save it before you quit the game. -== В редакторе есть несохранённая карта +== В редакторе есть несохранённая карта! Time limit -== Лимит на время +== Лимит времени Time limit: %d min -== Лимит на время: %d мин +== Лимит времени: %d мин Try again -== Попробовать ещё раз +== Ещё раз Type == Тип @@ -608,16 +617,16 @@ UI Color == Цвет интерфейса Unable to delete the demo -== Невозможно удалить демо +== Ошибка удаления демо Unable to rename the demo -== Невозможно переименовать демо +== Ошибка переименования демо Use sounds -== Звук +== Использовать звуки Use team colors for name plates -== Использовать цвет команды для имён игроков +== Красить ники в цвет команды V-Sync == Вертикальная синхронизация @@ -629,10 +638,10 @@ Version: == Версия: Vote command: -== Голосование: +== Команда серверу: Vote description: -== Причина голосования: +== Описание голосования: Vote no == Против @@ -644,7 +653,7 @@ Voting == Голосование Warmup -== Разогрев +== Разминка Weapon == Оружие @@ -656,7 +665,7 @@ Yes == Да You must restart the game for all settings to take effect. -== Вы должны перезапустить игру, чтобы настройки применились. +== Перезапустить игру, чтобы новые настройки применились. Your skin == Ваш скин @@ -666,14 +675,5 @@ no limit ##### needs translation ##### -Demofile: %s -== - -Player country: -== - -Strict gametype filter -== - ##### old translations ##### -- cgit 1.4.1 From ad0c58dbef39c6fcafbfc95d61dd4ff5d1be45a1 Mon Sep 17 00:00:00 2001 From: arionwt1997 Date: Thu, 7 Jul 2011 00:39:05 -0700 Subject: Update 10:40 07.07.2011 by Arion WT --- data/languages/russian.txt | 195 ++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 98 deletions(-) diff --git a/data/languages/russian.txt b/data/languages/russian.txt index 2200bb25..32215ebc 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -1,4 +1,3 @@ - ##### translated strings ##### %d Bytes @@ -14,19 +13,19 @@ == осталось %d сек. %i minute left -== осталась %i минута! +== Осталась %i минута! %i minutes left -== остались %i минут(ы) +== Осталось %i минут! %i second left -== осталась %i секунда! +== Осталась %i секунда! %i seconds left -== остались %i секунд(ы) +== Осталось %i секунд! %s wins! -== %s победил! +== %s победил! -Page %d- == -Страница %d- @@ -44,31 +43,31 @@ Address == Адрес All -== Всем +== Все Alpha == Прозрачн. Always show name plates -== Всегда показывать имена игроков +== Всегда показывать ники игроков Are you sure that you want to delete the demo? -== Вы действительно хотите удалить это демо? +== Вы уверены, что хотите удалить демо? Are you sure that you want to quit? -== Вы действительно хотите выйти? +== Вы действительно желаете выйти? Are you sure that you want to remove the player from your friends list? -== Вы действительно хотите удалить этого игрока из списка друзей? +== Вы уверены, что хотите удалить игрока из друзей? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Вы запустили игру первый раз, пожалуйста, введите ваш никнейм. Также мы рекомендуем вам настроить игру под себя в меню "Настройки". +== Так как это ваш первый запуск игры, пожалуйста, введите свой ник в поле ниже. Также рекоммендуется проверить настройки игры и поменять некоторые из них перед тем, как начать играть. Automatically record demos -== Записывать демо автоматически +== Автоматически записывать демо Automatically take game over screenshot -== Автоматически снимать итоги игры +== Делать снимок результатов игры Blue team == Синие @@ -83,7 +82,7 @@ Call vote == Голосовать Change settings -== Настройки +== Изменить настройки Chat == Чат @@ -95,7 +94,7 @@ Client == Клиент Close -== Выйти +== Выход Compatible version == Совместимая версия @@ -104,7 +103,7 @@ Connect == Подключиться Connecting to -== Подключаемся к +== Подключение к Connection Problems... == Проблемы со связью... @@ -119,10 +118,10 @@ Count players only == Считать только игроков Country -== Флаг +== Флаг вашей страны Crc: -== Crc-хэш: +== Crc: Created: == Создан: @@ -143,7 +142,7 @@ Delete demo == Удалить демо Demo details -== Подробнее про это демо +== Детали демо Demofile: %s == Демо: %s @@ -152,43 +151,43 @@ Demos == Демо Disconnect -== Отключиться +== Отключить Disconnected -== Отсоединен +== Отключено Display Modes -== Режим отображения +== Разрешение экрана Downloading map -== Загрузка карты +== Скачивание карты Draw! == Ничья! Dynamic Camera -== Подвижная камера +== Динамическая камера Emoticon == Эмоции Enter -== Войти +== Вход Error == Ошибка Error loading demo -== Ошибка при загрузке демо +== ошибка при загрузке демо FSAA samples -== FSAA сэмплы +== Сэмплов FSAA Favorite -== Избранный сервер +== Избранный Favorites -== Избранное +== Избранные Feet == Ноги @@ -197,28 +196,28 @@ Filter == Фильтр Fire -== Стрельба +== Выстрел Folder == Папка Force vote -== Применить +== Форсировать Free-View -== Свободный просмотр +== Свободный обзор Friends == Друзья Fullscreen -== На весь экран +== Полноэкранный режим Game == Игра Game info -== Подробности +== Инфо об игре Game over == Игра окончена @@ -227,7 +226,7 @@ Game type == Тип игры Game types: -== Типы игры: +== Тип игры: General == Основные @@ -239,16 +238,16 @@ Grenade == Гранатомёт Hammer -== Молоток +== Молот Has people playing -== Есть игроки на сервере +== Не пустой сервер High Detail == Высокая детализация Hook -== Цепь +== Крюк Host address == Адрес сервера @@ -263,22 +262,22 @@ Internet == Интернет Invalid Demo -== Нерабочее демо +== Недопустимое демо Join blue -== К синим +== За синих Join game -== В игру +== Играть Join red -== К красным +== За красных Jump == Прыжок Kick player -== Кикнуть игрока +== Забанить игрока LAN == LAN @@ -287,7 +286,7 @@ Language == Язык Length: -== Длина: +== Длина Lht. == Яркость @@ -305,10 +304,10 @@ Map: == Карта: Max Screenshots -== Максимум скриншотов +== Максимальное количество снимков Max demos -== Максимум демо +== Максимальное количество демо Maximum ping: == Макс. пинг: @@ -317,7 +316,7 @@ Miscellaneous == Дополнительно Mouse sens. -== Чувст. мыши +== Чувств. мыши Move left == Шаг влево @@ -329,22 +328,22 @@ Move right == Шаг вправо Movement -== Движение +== Перемещение Mute when not active -== Выключать звук, если игра свёрнута +== Глушить звуки, когда игра неактивна Name == Имя Name plates size -== Размер имён над игроками +== Размер Netversion: == Версия: New name: -== Новое имя: +== Новое имя News == Новости @@ -374,13 +373,13 @@ Open == Открыть Parent Folder -== На уровень выше +== Родительский каталог Password == Пароль Password incorrect -== Неверный пароль +== Пароль Ping == Пинг @@ -389,7 +388,7 @@ Pistol == Пистолет Play -== Запустить +== Просмотр Play background music == Играть фоновую музыку @@ -401,13 +400,13 @@ Player country: == Страна: Player options -== Настройки игроков +== Опции игрока Players == Игроки Please balance teams! -== Пожалуйста, cбалансируйте команды! +== Сбалансируйте команды! Prev. weapon == Пред. оружие @@ -422,7 +421,7 @@ Quit == Выход Quit anyway? -== Всё равно выйти? +== Выйти? REC %3d:%02d == REC %3d:%02d @@ -443,7 +442,7 @@ Refresh == Обновить Refreshing master servers -== Обновляем мастер-сервера +== Обновление списка мастер-серверов Remote console == Консоль сервера @@ -452,22 +451,22 @@ Remove == Удалить Remove friend -== Удалить из друзей +== Удалить друга Rename -== Сменить имя +== Переименов. Rename demo -== Сменить имя демо +== Переименовать демо Reset filter -== Сбросить фильтр +== Сбросить фильтры Reset to defaults == Сбросить настройки Rifle -== Лазер +== Бластер Round == Раунд @@ -479,31 +478,31 @@ Sat. == Контраст Score -== Счёт +== Очки Score board -== Ход игры +== Табло Score limit -== Лимит счёта +== Лимит очков Scoreboard -== Ход игры +== Табло Screenshot -== Скриншот +== Снимок Server address: -== Адрес сервера: +== Адрес сервера Server details -== Основное +== Детали сервера Server filter -== Фильтр +== Фильтр серверов Server info -== О сервере +== Информация Server not full == Сервер не заполнен @@ -518,22 +517,22 @@ Show chat == Показать чат Show friends only -== Только друзья +== Только с друзьями Show ingame HUD -== Показывать HUD +== Показывать внутриигровой HUD Show name plates -== Показывать имена над игроками +== Показывать ники игроков Show only supported -== Показывать только поддерживаемые +== Показывать только поддерживаемые разрешения экрана Size: == Размер: Skins -== Доступные скины +== Скины Sound == Звук @@ -542,16 +541,16 @@ Sound error == Звуковая ошибка Sound volume -== Громкость +== Громкость звука Spectate == Наблюдать Spectate next -== Наблюдать следующего +== Наблюдать след. Spectate previous -== Наблюдать предыдущего +== Наблюдать пред. Spectator mode == Наблюдатель @@ -566,46 +565,46 @@ Standard map == Стандартная карта Stop record -== Выкл. запись +== Стоп Strict gametype filter -== Строгий фильтр режимов +== Строгий фильтр режим. Sudden Death -== Внезапная смерть +== Быстрая смерть Switch weapon on pickup -== Сменять оружие на подобранное +== Переключать оружие при подборе Team -== Команде +== Команда Team chat == Командный чат Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s вышел! Скачайте его на www.teeworlds.com! +== Вышла Teeworlds %s! Скачивайте на www.teeworlds.com! Texture Compression == Сжатие текстур The audio device couldn't be initialised. -== Аудио устройство не может быть инициализировано. +== Аудио устройство не может быть инициализировано The server is running a non-standard tuning on a pure game type. -== Этот сервер работает на нестандартных настройках стандартного типа игры. +== Сервер запущен с нестандартными настройками на стандартном типе игры. There's an unsaved map in the editor, you might want to save it before you quit the game. -== В редакторе есть несохранённая карта! +== Есть несохранённая карта в редакторе, Вы можете сохранить её перед тем, как выйти. Time limit == Лимит времени Time limit: %d min -== Лимит времени: %d мин +== Лимит времени: %d Try again -== Ещё раз +== ОК Type == Тип @@ -617,16 +616,16 @@ UI Color == Цвет интерфейса Unable to delete the demo -== Ошибка удаления демо +== Невозможно удалить демо Unable to rename the demo -== Ошибка переименования демо +== Невозможно переименовать демо Use sounds == Использовать звуки Use team colors for name plates -== Красить ники в цвет команды +== Командные цвета для ников игроков V-Sync == Вертикальная синхронизация @@ -638,7 +637,7 @@ Version: == Версия: Vote command: -== Команда серверу: +== Комманда голосования: Vote description: == Описание голосования: @@ -665,7 +664,7 @@ Yes == Да You must restart the game for all settings to take effect. -== Перезапустить игру, чтобы новые настройки применились. +== Перезапустите игру для применения изменений. Your skin == Ваш скин @@ -675,5 +674,5 @@ no limit ##### needs translation ##### -##### old translations ##### +##### old translations ##### \ No newline at end of file -- cgit 1.4.1 From f44094490549a46781a7d85a137ddf748021d00f Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 8 Jul 2011 00:00:38 +0200 Subject: fixed problem with rcon authentication --- src/engine/server/server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index a707b690..24d3b317 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -840,7 +840,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) { SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password to enable the remote console."); } - else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0) + else if(g_Config.m_SvRconPassword[0] && str_comp(pPw, g_Config.m_SvRconPassword) == 0) { CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); Msg.AddInt(1); @@ -852,7 +852,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (admin)", ClientID); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); } - else if(str_comp(pPw, g_Config.m_SvRconModPassword) == 0) + else if(g_Config.m_SvRconModPassword[0] && str_comp(pPw, g_Config.m_SvRconModPassword) == 0) { CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); Msg.AddInt(1); -- cgit 1.4.1 From 7bc07b613f9fed3dcef26f63332ea68db1e1f381 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 9 Jul 2011 01:09:06 +0200 Subject: added auto mapping feature by LordSkelethom --- data/editor/desert_main.rules | 227 ++++++++++++++++++++++++++++++++++++++++ data/editor/grass_main.rules | 225 +++++++++++++++++++++++++++++++++++++++ data/editor/jungle_main.rules | 220 ++++++++++++++++++++++++++++++++++++++ data/editor/winter_main.rules | 177 +++++++++++++++++++++++++++++++ src/game/editor/auto_map.cpp | 202 +++++++++++++++++++++++++++++++++++ src/game/editor/auto_map.h | 54 ++++++++++ src/game/editor/editor.cpp | 12 ++- src/game/editor/editor.h | 19 +++- src/game/editor/io.cpp | 3 + src/game/editor/layer_tiles.cpp | 24 ++++- src/game/editor/popups.cpp | 44 ++++++++ 11 files changed, 1194 insertions(+), 13 deletions(-) create mode 100644 data/editor/desert_main.rules create mode 100644 data/editor/grass_main.rules create mode 100644 data/editor/jungle_main.rules create mode 100644 data/editor/winter_main.rules create mode 100644 src/game/editor/auto_map.cpp create mode 100644 src/game/editor/auto_map.h diff --git a/data/editor/desert_main.rules b/data/editor/desert_main.rules new file mode 100644 index 00000000..0102a197 --- /dev/null +++ b/data/editor/desert_main.rules @@ -0,0 +1,227 @@ +[Desert] +Index 1 +BaseTile + +#random +Index 2 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 3 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +#top +Index 16 +Pos 0 -1 EMPTY + +#right +Index 17 +Pos 1 0 EMPTY + +#bottom +Index 18 +Pos 0 1 EMPTY + +#left +Index 19 +Pos -1 0 EMPTY + +#corner top-right +Index 33 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 32 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 35 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 34 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 51 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 50 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 49 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 48 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL + +[Mine] +Index 81 +BaseTile + +#random +Index 82 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 83 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 84 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 85 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 86 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 100 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 101 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 102 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 117 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 118 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 133 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 134 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +#top +Index 96 +Pos 0 -1 EMPTY + +#right +Index 97 +Pos 1 0 EMPTY + +#bottom +Index 98 +Pos 0 1 EMPTY + +#left +Index 99 +Pos -1 0 EMPTY + +#corner top-right +Index 113 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 112 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 115 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 114 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 131 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 130 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 129 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 128 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL diff --git a/data/editor/grass_main.rules b/data/editor/grass_main.rules new file mode 100644 index 00000000..b909eb0e --- /dev/null +++ b/data/editor/grass_main.rules @@ -0,0 +1,225 @@ +[Grass] +Index 1 +BaseTile + +#random bones +Index 2 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 3 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 66 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 67 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 68 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 +#--------- + +#top +Index 16 +Pos 0 -1 EMPTY + +#right +Index 21 +Pos 1 0 EMPTY + +#bottom +Index 52 +Pos 0 1 EMPTY + +#left +Index 20 +Pos -1 0 EMPTY + +#corner top-right +Index 5 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 4 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 36 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 37 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 54 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 53 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 49 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 48 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL + +#right bottom +Index 22 +Pos -1 0 EMPTY +Pos -1 1 FULL +Pos 0 1 FULL + +#left bottom +Index 38 +Pos 1 0 EMPTY +Pos 1 1 FULL +Pos 0 1 FULL + +#top corner right 2 +Index 33 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos 1 1 FULL + +#top corner left 2 +Index 32 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY +Pos -1 1 FULL + +[Cave] +Index 13 +BaseTile + +#random bones +Index 29 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 42 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 43 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 44 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 45 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 +#--------- + +#top +Index 26 +Pos 0 -1 EMPTY + +#right +Index 25 +Pos 1 0 EMPTY + +#bottom +Index 10 +Pos 0 1 EMPTY + +#left +Index 24 +Pos -1 0 EMPTY + +#corner top-right +Index 9 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 8 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 40 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 41 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 12 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 11 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 27 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 28 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL diff --git a/data/editor/jungle_main.rules b/data/editor/jungle_main.rules new file mode 100644 index 00000000..3b967020 --- /dev/null +++ b/data/editor/jungle_main.rules @@ -0,0 +1,220 @@ +[Jungle] +Index 1 +BaseTile + +#random bricks +Index 66 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 67 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +#top +Index 16 +Pos 0 -1 EMPTY + +Index 96 +Pos 0 -1 EMPTY +Random 4 + +Index 97 +Pos 0 -1 EMPTY +Random 4 + +Index 98 +Pos 0 -1 EMPTY +Random 4 + +#right +Index 21 +Pos 1 0 EMPTY + +#bottom +Index 52 +Pos 0 1 EMPTY + +Index 99 +Pos 0 1 EMPTY +Random 4 + +Index 100 +Pos 0 1 EMPTY +Random 4 + +Index 101 +Pos 0 1 EMPTY +Random 4 + +#left +Index 21 XFLIP +Pos -1 0 EMPTY + +#corner top-right +Index 5 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 5 XFLIP +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 37 XFLIP +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 37 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 54 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 54 XFLIP +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 48 XFLIP +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 48 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL + +#right bottom +Index 22 +Pos -1 0 EMPTY +Pos -1 1 FULL +Pos 0 1 FULL + +#left bottom +Index 22 XFLIP +Pos 1 0 EMPTY +Pos 1 1 FULL +Pos 0 1 FULL + +#top corner right 2 +Index 33 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos 1 1 FULL + +#top corner left 2 +Index 32 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY +Pos -1 1 FULL + +[Jungle dark] +Index 13 +BaseTile + +#random bricks +Index 42 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 43 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 44 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 45 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 +#--------- + +#top +Index 26 +Pos 0 -1 EMPTY + +#right +Index 25 +Pos 1 0 EMPTY + +#bottom +Index 10 +Pos 0 1 EMPTY + +#left +Index 24 +Pos -1 0 EMPTY + +#corner top-right +Index 9 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 8 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 40 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 41 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 12 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 11 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 27 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 28 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL diff --git a/data/editor/winter_main.rules b/data/editor/winter_main.rules new file mode 100644 index 00000000..eaeaec8e --- /dev/null +++ b/data/editor/winter_main.rules @@ -0,0 +1,177 @@ +[Winter] +Index 1 +BaseTile + +#top +Index 17 +Pos 0 -1 EMPTY + +Index 18 +Pos 0 -1 EMPTY +Pos -1 0 INDEX 17 + +Index 19 +Pos 0 -1 EMPTY +Pos -1 0 INDEX 18 + +#bottom +Index 97 +Pos 0 1 EMPTY + +Index 98 +Pos 0 1 EMPTY +Pos -1 0 INDEX 97 + +Index 99 +Pos 0 1 EMPTY +Pos -1 0 INDEX 98 + +#right +Index 2 XFLIP +Pos 1 0 EMPTY + +#left +Index 2 +Pos -1 0 EMPTY + +#corner top right +Index 20 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +Index 24 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos -1 0 INDEX 17 + +#corner top left +Index 16 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom right +Index 100 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#corner bottom left +Index 96 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#inside corner top right +Index 8 +Pos 0 1 FULL +Pos -1 0 FULL +Pos -1 1 EMPTY + +#inside corner top left +Index 7 +Pos 0 1 FULL +Pos 1 0 FULL +Pos 1 1 EMPTY + +#inside corner bottom right +Index 4 +Pos 0 -1 FULL +Pos -1 0 FULL +Pos -1 -1 EMPTY + +#inside corner bottom left +Index 3 +Pos 0 -1 FULL +Pos 1 0 FULL +Pos 1 -1 EMPTY + +#one tile height +Index 113 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY + +Index 114 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos -1 0 INDEX 113 + +Index 115 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos -1 0 INDEX 114 + +#one tile height right +Index 116 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +Index 120 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos -1 0 INDEX 113 + +#one tile height left +Index 112 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#one tile height link right +Index 6 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL +Pos -1 1 EMPTY + +#one tile height link left +Index 5 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL +Pos 1 1 EMPTY + +[Winter dark] +Index 177 +BaseTile + +#bottom +Index 194 +Pos 0 1 EMPTY + +Index 195 +Pos 0 1 EMPTY +Pos -1 0 INDEX 194 + +Index 196 +Pos 0 1 EMPTY +Pos -1 0 INDEX 195 + +#right +Index 178 XFLIP +Pos 1 0 EMPTY + +#left +Index 178 +Pos -1 0 EMPTY + +#corner bottom right +Index 197 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#corner bottom left +Index 193 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#inside corner top right +Index 180 +Pos 0 1 FULL +Pos -1 0 FULL +Pos -1 1 EMPTY + +#inside corner top left +Index 179 +Pos 0 1 FULL +Pos 1 0 FULL +Pos 1 1 EMPTY diff --git a/src/game/editor/auto_map.cpp b/src/game/editor/auto_map.cpp new file mode 100644 index 00000000..528e459b --- /dev/null +++ b/src/game/editor/auto_map.cpp @@ -0,0 +1,202 @@ +#include // sscanf + +#include +#include +#include + +#include "auto_map.h" +#include "editor.h" + +CAutoMapper::CAutoMapper(CEditor *pEditor) +{ + m_pEditor = pEditor; + m_FileLoaded = false; +} + +void CAutoMapper::Load(const char* pTileName) +{ + char aPath[256]; + str_format(aPath, sizeof(aPath), "editor/%s.rules", 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()) + { + // skip blank/empty lines as well as comments + if(str_length(pLine) > 0 && pLine[0] != '#' && pLine[0] != '\n' && pLine[0] != '\r' + && pLine[0] != '\t' && pLine[0] != '\v' && pLine[0] != ' ') + { + if(pLine[0]== '[') + { + // 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 + { + if(!str_comp_num(pLine, "Index", 5)) + { + // 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")) + NewIndexRule.m_Flag = TILEFLAG_VFLIP; + 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]; + } + else if(!str_comp_num(pLine, "BaseTile", 8) && pCurrentIndex) + { + pCurrentIndex->m_BaseTile = true; + } + else if(!str_comp_num(pLine, "Pos", 3) && pCurrentIndex) + { + int x = 0, y = 0; + 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)) + { + sscanf(pLine, "Pos %*d %*d INDEX %d", &Value); + IndexValue = true; + } + + CPosRule NewPosRule = {x, y, Value, IndexValue}; + pCurrentIndex->m_aRules.add(NewPosRule); + } + else if(!str_comp_num(pLine, "Random", 6) && pCurrentIndex) + { + sscanf(pLine, "Random %d", &pCurrentIndex->m_RandomValue); + } + } + } + } + + io_close(RulesFile); + + str_format(aBuf, sizeof(aBuf),"loaded %s", aPath); + m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "editor", aBuf); + + m_FileLoaded = true; +} + +const char* CAutoMapper::GetConfigName(int Index) +{ + if(Index < 0 || Index >= m_lConfigs.size()) + return ""; + + return m_lConfigs[Index].m_aName; +} + +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) + { + if(pConf->m_aIndexRules[i].m_BaseTile) + { + BaseTile = pConf->m_aIndexRules[i].m_ID; + break; + } + } + + // auto map ! + int MaxIndex = pLayer->m_Width*pLayer->m_Height; + for(int y = 0; y < pLayer->m_Height; y++) + for(int x = 0; x < pLayer->m_Width; x++) + { + CTile *pTile = &(pLayer->m_pTiles[y*pLayer->m_Width+x]); + if(pTile->m_Index == 0) + continue; + + pTile->m_Index = BaseTile; + m_pEditor->m_Map.m_Modified = true; + + 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) + continue; + + bool RespectRules = true; + for(int j = 0; j < pConf->m_aIndexRules[i].m_aRules.size() && RespectRules; ++j) + { + 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 + { + if(pRule->m_IndexValue) + { + if(pLayer->m_pTiles[CheckIndex].m_Index != pRule->m_Value) + RespectRules = false; + } + else + { + 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)) + { + 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 new file mode 100644 index 00000000..4f4cf92e --- /dev/null +++ b/src/game/editor/auto_map.h @@ -0,0 +1,54 @@ +#ifndef GAME_EDITOR_ED_AUTO_MAP_H +#define GAME_EDITOR_ED_AUTO_MAP_H + +#include + +class CAutoMapper +{ + struct CPosRule + { + int m_X; + int m_Y; + int m_Value; + bool m_IndexValue; + + enum + { + EMPTY=0, + FULL + }; + }; + + struct CIndexRule + { + int m_ID; + array m_aRules; + int m_Flag; + int m_RandomValue; + bool m_BaseTile; + }; + + struct CConfiguration + { + 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; + class CEditor *m_pEditor; + bool m_FileLoaded; +}; + + +#endif diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index bc00c4a2..907552dc 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -8,20 +8,20 @@ #include #include #include -#include #include #include #include +#include -#include #include +#include +#include #include +#include #include +#include "auto_map.h" #include "editor.h" -#include - -#include int CEditor::ms_CheckerTexture; int CEditor::ms_BackgroundTexture; @@ -1899,6 +1899,7 @@ void CEditor::ReplaceImage(const char *pFileName, int StorageType, void *pUser) *pImg = ImgInfo; pImg->m_External = External; pEditor->ExtractName(pFileName, pImg->m_aName, sizeof(pImg->m_aName)); + pImg->m_AutoMapper.Load(pImg->m_aName); pImg->m_TexID = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); pEditor->SortImages(); for(int i = 0; i < pEditor->m_Map.m_lImages.size(); ++i) @@ -1930,6 +1931,7 @@ void CEditor::AddImage(const char *pFileName, int StorageType, void *pUser) pImg->m_TexID = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); pImg->m_External = 1; // external by default str_copy(pImg->m_aName, aBuf, sizeof(pImg->m_aName)); + pImg->m_AutoMapper.Load(pImg->m_aName); pEditor->m_Map.m_lImages.add(pImg); pEditor->SortImages(); if(pEditor->m_SelectedImage > -1 && pEditor->m_SelectedImage < pEditor->m_Map.m_lImages.size()) diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index c7779954..353b0774 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -3,23 +3,26 @@ #ifndef GAME_EDITOR_EDITOR_H #define GAME_EDITOR_EDITOR_H -#include +#include + #include -#include +#include + #include +#include #include #include -#include +#include #include #include -#include #include +#include #include #include -#include +#include "auto_map.h" typedef void (*INDEX_MODIFY_FUNC)(int *pIndex); @@ -230,6 +233,7 @@ public: CEditor *m_pEditor; CEditorImage(CEditor *pEditor) + : m_AutoMapper(pEditor) { m_pEditor = pEditor; m_TexID = -1; @@ -249,6 +253,7 @@ public: int m_External; char m_aName[128]; unsigned char m_aTileFlags[256]; + class CAutoMapper m_AutoMapper; }; class CEditorMap @@ -684,6 +689,7 @@ public: static int PopupSelectGametileOp(CEditor *pEditor, CUIRect View); static int PopupImage(CEditor *pEditor, CUIRect View); static int PopupMenuFile(CEditor *pEditor, CUIRect View); + static int PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View); static void CallbackOpenMap(const char *pFileName, int StorageType, void *pUser); static void CallbackAppendMap(const char *pFileName, int StorageType, void *pUser); @@ -694,6 +700,9 @@ public: void PopupSelectGametileOpInvoke(float x, float y); int PopupSelectGameTileOpResult(); + + void PopupSelectConfigAutoMapInvoke(float x, float y); + int PopupSelectConfigAutoMapResult(); vec4 ButtonColorMul(const void *pID); diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 7207e49f..987404b8 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -449,6 +449,9 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag if(pName) str_copy(pImg->m_aName, pName, 128); + // load auto mapper file + pImg->m_AutoMapper.Load(pImg->m_aName); + m_lImages.add(pImg); // unload image diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index b792eda9..81944636 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -360,14 +360,32 @@ void CLayerTiles::ShowInfo() int CLayerTiles::RenderProperties(CUIRect *pToolBox) { CUIRect Button; - pToolBox->HSplitBottom(12.0f, pToolBox, &Button); - + bool InGameGroup = !find_linear(m_pEditor->m_Map.m_pGameGroup->m_lLayers.all(), this).empty(); - if(m_pEditor->m_Map.m_pGameLayer == this) + if(m_pEditor->m_Map.m_pGameLayer != this) + { + if(m_Image >= 0 && m_Image < m_pEditor->m_Map.m_lImages.size() && m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.IsLoaded()) + { + static int s_AutoMapperButton = 0; + 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) + { + m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.Proceed(this, Result); + return 1; + } + } + } + else InGameGroup = false; if(InGameGroup) { + pToolBox->HSplitBottom(2.0f, pToolBox, 0); + pToolBox->HSplitBottom(12.0f, pToolBox, &Button); static int s_ColclButton = 0; if(m_pEditor->DoButton_Editor(&s_ColclButton, "Game tiles", 0, &Button, 0, "Constructs game tiles from this layer")) m_pEditor->PopupSelectGametileOpInvoke(m_pEditor->UI()->MouseX(), m_pEditor->UI()->MouseY()); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 3ae29725..0a691fdf 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -1,10 +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 #include #include #include #include + #include "editor.h" @@ -737,3 +741,43 @@ int CEditor::PopupSelectGameTileOpResult() s_GametileOpSelected = -1; return Result; } + +static int s_AutoMapConfigSelected = -1; + +int CEditor::PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View) +{ + CLayerTiles *pLayer = static_cast(pEditor->GetSelectedLayer(0)); + 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); + View.HSplitTop(12.0f, &Button, &View); + if(pEditor->DoButton_Editor(&s_AutoMapperConfigButtons[i], pAutoMapper->GetConfigName(i), 0, &Button, 0, 0)) + s_AutoMapConfigSelected = i; + } + + return 0; +} + +void CEditor::PopupSelectConfigAutoMapInvoke(float x, float y) +{ + static int s_AutoMapConfigSelectID = 0; + s_AutoMapConfigSelected = -1; + CLayerTiles *pLayer = static_cast(GetSelectedLayer(0)); + if(pLayer && pLayer->m_Image >= 0 && pLayer->m_Image < m_Map.m_lImages.size() && + m_Map.m_lImages[pLayer->m_Image]->m_AutoMapper.ConfigNamesNum()) + UiInvokePopupMenu(&s_AutoMapConfigSelectID, 0, x, y, 120.0f, 12.0f+14.0f*m_Map.m_lImages[pLayer->m_Image]->m_AutoMapper.ConfigNamesNum(), PopupSelectConfigAutoMap); +} + +int CEditor::PopupSelectConfigAutoMapResult() +{ + if(s_AutoMapConfigSelected < 0) + return -1; + + int Result = s_AutoMapConfigSelected; + s_AutoMapConfigSelected = -1; + return Result; +} -- cgit 1.4.1 From 1058fe27f2411f08918fc39183a6101b8d3c9f72 Mon Sep 17 00:00:00 2001 From: Romain Labolle Date: Sat, 9 Jul 2011 11:45:01 +0200 Subject: Allow multi-file input for dilate and tilset_borderfix commands --- src/tools/dilate.cpp | 24 +++++++++++++++++++----- src/tools/tileset_borderfix.cpp | 24 +++++++++++++++++++----- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/tools/dilate.cpp b/src/tools/dilate.cpp index ef862270..a4853e1c 100644 --- a/src/tools/dilate.cpp +++ b/src/tools/dilate.cpp @@ -48,18 +48,18 @@ static void CopyAlpha(int w, int h, CPixel *pSrc, CPixel *pDest) pDest[m].a = pSrc[m].a; } -int main(int argc, char **argv) +int DilateFile(const char *FileName) { png_t Png; CPixel *pBuffer[3] = {0,0,0}; png_init(0, 0); - png_open_file(&Png, argv[1]); + png_open_file(&Png, FileName); if(Png.color_type != PNG_TRUECOLOR_ALPHA) { - dbg_msg("dilate", "not an RGBA image"); - return -1; + dbg_msg("dilate", "%s : not an RGBA image", FileName); + return 1; } pBuffer[0] = (CPixel*)mem_alloc(Png.width*Png.height*sizeof(CPixel), 1); @@ -81,9 +81,23 @@ int main(int argc, char **argv) CopyAlpha(w, h, pBuffer[0], pBuffer[1]); // save here - png_open_file_write(&Png, argv[1]); + png_open_file_write(&Png, FileName); png_set_data(&Png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pBuffer[1]); png_close_file(&Png); return 0; } + +int main(int argc, const char **argv) +{ + dbg_logger_stdout(); + if(argc == 1) + { + dbg_msg("Usage", "%s FILE1 [ FILE2... ]", argv[0]); + return -1; + } + int errors=0; + for(int i=1;i Date: Mon, 11 Jul 2011 11:26:41 +0200 Subject: cleaned up last commit --- src/tools/dilate.cpp | 16 ++++++++-------- src/tools/tileset_borderfix.cpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/tools/dilate.cpp b/src/tools/dilate.cpp index a4853e1c..eb770a90 100644 --- a/src/tools/dilate.cpp +++ b/src/tools/dilate.cpp @@ -48,17 +48,17 @@ static void CopyAlpha(int w, int h, CPixel *pSrc, CPixel *pDest) pDest[m].a = pSrc[m].a; } -int DilateFile(const char *FileName) +int DilateFile(const char *pFileName) { png_t Png; CPixel *pBuffer[3] = {0,0,0}; png_init(0, 0); - png_open_file(&Png, FileName); + png_open_file(&Png, pFileName); if(Png.color_type != PNG_TRUECOLOR_ALPHA) { - dbg_msg("dilate", "%s : not an RGBA image", FileName); + dbg_msg("dilate", "%s: not an RGBA image", pFileName); return 1; } @@ -81,7 +81,7 @@ int DilateFile(const char *FileName) CopyAlpha(w, h, pBuffer[0], pBuffer[1]); // save here - png_open_file_write(&Png, FileName); + png_open_file_write(&Png, pFileName); png_set_data(&Png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pBuffer[1]); png_close_file(&Png); @@ -96,8 +96,8 @@ int main(int argc, const char **argv) dbg_msg("Usage", "%s FILE1 [ FILE2... ]", argv[0]); return -1; } - int errors=0; - for(int i=1;i Date: Sun, 10 Jul 2011 13:02:13 +0200 Subject: Display a message when an admin forces a vote. Closes #759 --- src/game/server/gamecontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index a8b2f379..52eaca89 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1264,6 +1264,8 @@ void CGameContext::ConForceVote(IConsole::IResult *pResult, void *pUserData) return; } + str_format(aBuf, sizeof(aBuf), "admin moved '%s' to spectator (%s)", pSelf->Server()->ClientName(SpectateID), pReason); + pSelf->SendChatTarget(-1, aBuf); str_format(aBuf, sizeof(aBuf), "set_team %d -1 %d", SpectateID, g_Config.m_SvVoteSpectateRejoindelay); pSelf->Console()->ExecuteLine(aBuf); } @@ -1290,6 +1292,8 @@ void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData) else if(str_comp_nocase(pResult->GetString(0), "no") == 0) pSelf->m_VoteEnforce = CGameContext::VOTE_ENFORCE_NO; char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "admin forced vote %s", pResult->GetString(0)); + pSelf->SendChatTarget(-1, aBuf); str_format(aBuf, sizeof(aBuf), "forcing vote %s", pResult->GetString(0)); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); } -- cgit 1.4.1 From f0bc14466ac4439dd6ebf77a4a07090875fb93dd Mon Sep 17 00:00:00 2001 From: Alexandre Date: Sun, 10 Jul 2011 15:30:05 -0700 Subject: Edited data/languages/spanish.txt via GitHub --- data/languages/spanish.txt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/data/languages/spanish.txt b/data/languages/spanish.txt index f54dc175..42105d43 100644 --- a/data/languages/spanish.txt +++ b/data/languages/spanish.txt @@ -1,4 +1,3 @@ - ##### translated strings ##### %d Bytes @@ -335,7 +334,7 @@ Name == Nombre Name plates size -== Máx. Caracteres para los Apodos +== Tamaño de la Fuente (%) Netversion: == Versión Net @@ -641,7 +640,7 @@ Weapon == Arma Welcome to Teeworlds -== Bienvenido a Teeworlds! +== Bienvenido/a a Teeworlds! Yes == Si @@ -658,22 +657,22 @@ no limit ##### needs translation ##### Demofile: %s -== +== Archivo Demo: %s Play background music -== +== Reproducir música de fondo Player country: -== +== Tú Pais Spectate next -== +== Observar siguiente Spectate previous -== +== Observar anterior Strict gametype filter -== +== Filtro estricto gametype ##### old translations ##### -- cgit 1.4.1 From 12c453ab15cec191c84afdf20427d5c22f5e3a9c Mon Sep 17 00:00:00 2001 From: Aline aka Ryomou Hentai Girl Date: Sun, 10 Jul 2011 20:30:28 -0700 Subject: Portuguese language updated. --- data/languages/portuguese.txt | 223 +++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 112 deletions(-) diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index fd484551..cbfdab89 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -1,32 +1,31 @@ - ##### translated strings ##### %d Bytes == %d Bytes %d of %d servers, %d players -== %d de %d servidores, %d jogadores +== %d de %d Servidores, %d Jogadores %d%% loaded -== %d%% carregado +== %d%% Carregado %ds left -== faltam %ds +== Faltam %ds %i minute left -== falta %i minuto +== Falta %i Minuto %i minutes left -== faltam %i minutos +== Faltam %i Minutos %i second left -== falta %i segundo +== Falta %i Segundo %i seconds left -== faltam %i segundos +== Faltam %i Segundos %s wins! -== %s vence! +== %s Vence! -Page %d- == -Página %d- @@ -53,13 +52,13 @@ Always show name plates == Sempre mostrar apelidos Are you sure that you want to delete the demo? -== Tem certeza que deseja deletar o demo? +== Tem certeza que deseja deletar o Demo? Are you sure that you want to quit? == Você tem certeza que deseja sair? Are you sure that you want to remove the player from your friends list? -== Tem certeza que deseja remover o jogador da sua lista de amigos? +== Tem certeza que deseja remover o Jogador de sua Lista de Amigos? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. == Como esta é a primeira vez que você abre o jogo, por favor, coloque seu apelido abaixo. É recomendado que você verifique as configurações e então ajuste-as para suas preferências antes de entrar em um servidor. @@ -71,25 +70,25 @@ Automatically take game over screenshot == Capturar tela final de jogo automaticamente Blue team -== Time azul +== Time Azul Blue team wins! -== Time azul vence! +== Vitória do Time Azul! Body == Corpo Call vote -== Votação +== Votar Change settings -== Mudar configurações +== Mudar Configurações Chat -== Conversa +== Chat Clan -== Clan +== Clã Client == Cliente @@ -98,7 +97,7 @@ Close == Fechar Compatible version -== Versão compatível +== Versão Compatível Connect == Conectar @@ -116,7 +115,7 @@ Controls == Controles Count players only -== Contar apenas jogadores +== Contar apenas Jogadores Country == País @@ -128,22 +127,22 @@ Created: == Criado: Current -== Atualmente +== Atual Current version: %s -== Versão atual : %s +== Versão atual: %s Custom colors -== Cores personalizadas +== Cores Personalizadas Delete == Deletar Delete demo -== Deletar demo +== Deletar Demo Demo details -== Detalhes do demo +== Detalhes do Demo Demofile: %s == Demo: %s @@ -167,7 +166,7 @@ Draw! == Empate! Dynamic Camera -== Câmera dinâmica +== Câmera Dinâmica Emoticon == Emoticon @@ -179,7 +178,7 @@ Error == Erro Error loading demo -== Erro ao carregar demo +== Erro ao carregar Demo FSAA samples == Amostras FSAA @@ -203,31 +202,31 @@ Folder == Pasta Force vote -== Forçar +== Forçar Votação Free-View -== Visão Livre +== Visualização Livre Friends == Amigos Fullscreen -== Tela cheia +== Tela Cheia Game == Jogo Game info -== Info sobre o jogo +== Jogo Game over -== Fim de Jogo +== Fim do Jogo Game type -== Tipo de jogo +== Tipo de Jogo Game types: -== Tipos de jogo: +== Tipos de Jogo: General == Geral @@ -242,43 +241,43 @@ Hammer == Martelo Has people playing -== Tem gente jogando +== Há pessoas jogando High Detail -== Mais detalhes (HD) +== Mostrar Detalhes Hook == Gancho Host address -== Endereço do host +== Endereço do Domínio Hue == Matiz Info -== Info. +== Informações Internet == Internet Invalid Demo -== Demo inválido +== Demo Inválido Join blue -== Azul +== Time Azul Join game -== Entre no jogo +== Entrar no Jogo Join red -== Vermelho +== Time Vermelho Jump == Pular Kick player -== Kickar jogador +== Expulsar Jogador LAN == LAN @@ -287,10 +286,10 @@ Language == Idioma Length: -== Duração: +== Comprimento: Lht. -== Luz +== Brilho. Loading == Carregando @@ -305,40 +304,40 @@ Map: == Mapa: Max Screenshots -== Máx. de Capturas de Tela +== Máximo de capturas de tela Max demos -== Máx. de demos +== Máximo de Demos Maximum ping: -== Ping máximo: +== Ping Máximo: Miscellaneous == Diversos Mouse sens. -== Sens. do mouse +== Sens. do Mouse Move left -== Esquerda +== Andar para Esquerda Move player to spectators -== Mover jogador para observadores +== Mover jogador para Espectadores Move right -== Direita +== Andar para Direita Movement == Movimento Mute when not active -== Silenciar quando inativo +== Silenciar quando Inativo Name == Nome Name plates size -== Tamanho dos apelidos +== Tamanho dos Apelidos Netversion: == Netversion @@ -347,7 +346,7 @@ New name: == Novo nome: News -== Notícia +== Novidades Next weapon == Próxima arma @@ -359,7 +358,7 @@ No == Não No password -== Sem senha +== Sem Senha No servers found == Nenhum servidor encontrado @@ -374,13 +373,13 @@ Open == Abrir Parent Folder -== Diretório pai +== Diretório Principal Password == Senha Password incorrect -== Senha incorreta +== Senha Incorreta Ping == Ping @@ -392,22 +391,22 @@ Play == Assistir Play background music -== Tocar música de fundo +== Tocar Música de Fundo Player == Jogador Player country: -== País do jogador: +== País do Jogador: Player options -== Opções do jogador +== Opções do Jogador Players == Jogadores Please balance teams! -== Por favor, balanceie os times! +== Favor balancear os Times! Prev. weapon == Arma anterior @@ -431,13 +430,13 @@ Reason: == Motivo: Record demo -== Gravar demo +== Gravar Demo Red team -== Time vermelho +== Time Vermelho Red team wins! -== Time vermelho vence! +== Vitória do Time Vermelho! Refresh == Atualizar @@ -452,19 +451,19 @@ Remove == Deletar Remove friend -== Deletar amigo +== Deletar Amigo Rename == Renomear Rename demo -== Renomear demo +== Renomear Demo Reset filter -== Resetar filtro +== Resetar Filtro Reset to defaults -== Resetar para padrão +== Configurações Padrão Rifle == Laser @@ -473,10 +472,10 @@ Round == Rodada Sample rate -== Taxa de som +== Frequência do Som Sat. -== Sat. +== Saturação. Score == Pontos @@ -485,28 +484,28 @@ Score board == Placar Score limit -== Placar máx. +== Pontuação Máxima Scoreboard == Placar Screenshot -== Captura de tela +== Capturar Tela Server address: -== End. do servidor: +== Endereço do Servidor: Server details -== Detalhes do server +== Detalhes do Servidor Server filter -== Filtro de server +== Filtro de Servidores Server info -== Info do server +== Servidor Server not full -== Servidor não cheio +== Servidor Não Lotado Settings == Configurações @@ -515,19 +514,19 @@ Shotgun == Espingarda Show chat -== Mostrar conversa +== Mostrar Chat Show friends only -== Mostrar amigos +== Mostrar Apenas Amigos Show ingame HUD -== Mostrar HUD do jogo +== Mostrar Display do Jogo Show name plates -== Mostrar apelidos +== Mostrar Apelidos Show only supported -== Mostrar apenas suportados +== Mostrar apenas o suportado Size: == Tamanho: @@ -539,10 +538,10 @@ Sound == Som Sound error -== Erro de som +== Erro de Som Sound volume -== Volume do som +== Volume do Som Spectate == Observar @@ -554,58 +553,58 @@ Spectate previous == Observar anterior Spectator mode -== Modo Observador +== Modo Espectador Spectators -== Observadores +== Espectadores Standard gametype -== Tipo de jogo padrão +== Tipo de Jogo Padrão Standard map -== Mapa padrão +== Mapa Padrão Stop record -== Parar a gravação +== Parar a Gravação Strict gametype filter -== Tipo de jogo exato +== Filtrar tipo Exato de Jogo Sudden Death == Morte Súbita Switch weapon on pickup -== Trocar arma ao pegar +== Mudar arma ao pegá-las Team == Time Team chat -== Conv. de equipe +== Chat do Time Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s foi lançado! Baixe-o em www.teeworlds.com! +== Teeworlds %s está pronto! Faça o Download em www.teeworlds.com! Texture Compression -== Compressão de Textura +== Compressão da Textura The audio device couldn't be initialised. -== O aparelho de áudio não pode ser inicializado. +== O Dispositivo de áudio não pôde ser inicializado. The server is running a non-standard tuning on a pure game type. -== O servidor está rodando uma modificação não padrão em um tipo de jogo puro. +== O Servidor está sendo executado com ajustes diferentes de seu Padrão Oficial de tipo de jogo. There's an unsaved map in the editor, you might want to save it before you quit the game. -== Existe um mapa não salvo no editor, você pode querer salvá-lo antes de sair do jogo. +== Existe um Mapa não salvo no editor, você deve querer salvá-lo antes de sair do jogo. Time limit -== Tempo máx. +== Limite de Tempo Time limit: %d min -== Limite de tempo: %d min +== Limite de tempo: %d Minutos Try again -== Tente de novo +== Tente Novamente Type == Tipo @@ -614,19 +613,19 @@ Type: == Tipo: UI Color -== Cor do menu +== Cor do Menu Unable to delete the demo -== Incapaz de deletar demo +== Não é possível deletar Demo Unable to rename the demo -== Incapaz de renomear demo +== Não é possível renomear Demo Use sounds -== Usar sons +== Usar Sons Use team colors for name plates -== Usar cores do time para apelidos +== Usar cores dos times em Apelidos V-Sync == V-Sync @@ -638,16 +637,16 @@ Version: == Versão Vote command: -== Comando: +== Comando para Votar: Vote description: -== Descrição da votação: +== Descrição da Votação: Vote no -== Votar não +== Vote Não Vote yes -== Votar sim +== Vote Sim Voting == Votação @@ -659,7 +658,7 @@ Weapon == Arma Welcome to Teeworlds -== Bem-vindo ao Teeworlds! +== Bem-Vindo ao Teeworlds! Yes == Sim @@ -668,10 +667,10 @@ You must restart the game for all settings to take effect. == Você deve reiniciar o jogo para que todas as alterações tenham efeito. Your skin -== Sua skin +== Sua Skin no limit -== sem limite +== Sem Limite ##### needs translation ##### -- cgit 1.4.1 From d28108b8ad25476ea5fc05836bea6a35205c7213 Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 11 Jul 2011 12:00:13 +0200 Subject: fixed few issues with masters.cfg --- src/engine/masterserver.h | 1 - src/engine/shared/masterserver.cpp | 90 +++++++++++++++++++++----------------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/engine/masterserver.h b/src/engine/masterserver.h index 74a394dc..57433993 100644 --- a/src/engine/masterserver.h +++ b/src/engine/masterserver.h @@ -23,7 +23,6 @@ public: virtual int RefreshAddresses(int Nettype) = 0; virtual void Update() = 0; virtual int IsRefreshing() = 0; - virtual void DumpServers() = 0; virtual NETADDR GetAddr(int Index) = 0; virtual const char *GetName(int Index) = 0; virtual bool IsValid(int Index) = 0; diff --git a/src/engine/shared/masterserver.cpp b/src/engine/shared/masterserver.cpp index 1bf402ca..1271eeaf 100644 --- a/src/engine/shared/masterserver.cpp +++ b/src/engine/shared/masterserver.cpp @@ -21,51 +21,57 @@ public: bool m_Valid; CHostLookup m_Lookup; - } ; + }; + + enum + { + STATE_INIT, + STATE_UPDATE, + STATE_READY, + }; CMasterInfo m_aMasterServers[MAX_MASTERSERVERS]; - int m_NeedsUpdate; + int m_State; IEngine *m_pEngine; IStorage *m_pStorage; CMasterServer() { SetDefault(); - m_NeedsUpdate = -1; + m_State = STATE_INIT; m_pEngine = 0; + m_pStorage = 0; } virtual int RefreshAddresses(int Nettype) { - int i; - - if(m_NeedsUpdate != -1) - return 0; + if(m_State != STATE_INIT) + return -1; dbg_msg("engine/mastersrv", "refreshing master server addresses"); // add lookup jobs - for(i = 0; i < MAX_MASTERSERVERS; i++) + for(int i = 0; i < MAX_MASTERSERVERS; i++) { m_pEngine->HostLookup(&m_aMasterServers[i].m_Lookup, m_aMasterServers[i].m_aHostname, Nettype); m_aMasterServers[i].m_Valid = false; } - m_NeedsUpdate = 1; + m_State = STATE_UPDATE; return 0; } virtual void Update() { // check if we need to update - if(m_NeedsUpdate != 1) + if(m_State != STATE_UPDATE) return; - m_NeedsUpdate = 0; + m_State = STATE_READY; for(int i = 0; i < MAX_MASTERSERVERS; i++) { if(m_aMasterServers[i].m_Lookup.m_Job.Status() != CJob::STATE_DONE) - m_NeedsUpdate = 1; + m_State = STATE_UPDATE; else { if(m_aMasterServers[i].m_Lookup.m_Job.Result() == 0) @@ -79,7 +85,7 @@ public: } } - if(!m_NeedsUpdate) + if(m_State == STATE_READY) { dbg_msg("engine/mastersrv", "saving addresses"); Save(); @@ -88,7 +94,7 @@ public: virtual int IsRefreshing() { - return m_NeedsUpdate; + return m_State != STATE_READY; } virtual NETADDR GetAddr(int Index) @@ -106,16 +112,6 @@ public: return m_aMasterServers[Index].m_Valid; } - virtual void DumpServers() - { - for(int i = 0; i < MAX_MASTERSERVERS; i++) - { - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr)); - dbg_msg("mastersrv", "#%d = %s", i, aAddrStr); - } - } - virtual void Init() { m_pEngine = Kernel()->RequestInterface(); @@ -131,17 +127,15 @@ public: virtual int Load() { - CLineReader LineReader; - IOHANDLE File; - int Count = 0; if(!m_pStorage) return -1; // try to open file - File = m_pStorage->OpenFile("masters.cfg", IOFLAG_READ, IStorage::TYPE_SAVE); + IOHANDLE File = m_pStorage->OpenFile("masters.cfg", IOFLAG_READ, IStorage::TYPE_SAVE); if(!File) return -1; + CLineReader LineReader; LineReader.Init(File); while(1) { @@ -152,19 +146,32 @@ public: // parse line char aAddrStr[NETADDR_MAXSTRSIZE]; - if(sscanf(pLine, "%s %s", Info.m_aHostname, aAddrStr) == 2 && net_addr_from_str(&Info.m_Addr, aAddrStr) == 0) + if(sscanf(pLine, "%127s %47s", Info.m_aHostname, aAddrStr) == 2 && net_addr_from_str(&Info.m_Addr, aAddrStr) == 0) { Info.m_Addr.port = 8300; - if(Count != MAX_MASTERSERVERS) + bool Added = false; + for(int i = 0; i < MAX_MASTERSERVERS; ++i) + if(str_comp(m_aMasterServers[i].m_aHostname, Info.m_aHostname) == 0) + { + m_aMasterServers[i] = Info; + Added = true; + break; + } + + if(!Added) { - m_aMasterServers[Count] = Info; - Count++; + for(int i = 0; i < MAX_MASTERSERVERS; ++i) + if(m_aMasterServers[i].m_Addr.type == NETTYPE_INVALID) + { + m_aMasterServers[i] = Info; + Added = true; + break; + } } - //else - // dbg_msg("engine/mastersrv", "warning: skipped master server '%s' due to limit of %d", pLine, MAX_MASTERSERVERS); + + if(!Added) + break; } - //else - // dbg_msg("engine/mastersrv", "warning: couldn't parse master server '%s'", pLine); } io_close(File); @@ -173,21 +180,22 @@ public: virtual int Save() { - IOHANDLE File; - if(!m_pStorage) return -1; // try to open file - File = m_pStorage->OpenFile("masters.cfg", IOFLAG_WRITE, IStorage::TYPE_SAVE); + IOHANDLE File = m_pStorage->OpenFile("masters.cfg", IOFLAG_WRITE, IStorage::TYPE_SAVE); if(!File) return -1; for(int i = 0; i < MAX_MASTERSERVERS; i++) { char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr)); - char aBuf[1024]; + if(m_aMasterServers[i].m_Addr.type != NETTYPE_INVALID) + net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr)); + else + aAddrStr[0] = 0; + char aBuf[256]; str_format(aBuf, sizeof(aBuf), "%s %s\n", m_aMasterServers[i].m_aHostname, aAddrStr); io_write(File, aBuf, str_length(aBuf)); -- cgit 1.4.1 From f4ce34f01c87e4edbfc085ea60ccec1e3b386f60 Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 11 Jul 2011 12:02:45 +0200 Subject: close spectator/emoticon menu when changing to team/spectator via bind. Closes #768 --- src/game/client/components/emoticon.cpp | 7 +++++++ src/game/client/components/spectator.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp index bedfaafb..b2f48b80 100644 --- a/src/game/client/components/emoticon.cpp +++ b/src/game/client/components/emoticon.cpp @@ -102,6 +102,13 @@ void CEmoticon::OnRender() return; } + if(m_pClient->m_Snap.m_SpecInfo.m_Active) + { + m_Active = false; + m_WasActive = false; + return; + } + m_WasActive = true; if (length(m_SelectorMouse) > 140) diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index c69a7669..c09b2ee2 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -162,6 +162,13 @@ void CSpectator::OnRender() return; } + if(!m_pClient->m_Snap.m_SpecInfo.m_Active) + { + m_Active = false; + m_WasActive = false; + return; + } + m_WasActive = true; m_SelectedSpectatorID = NO_SELECTION; -- cgit 1.4.1 From 6cd2ab38878cda02a6ff18bc87d8a694e43781bb Mon Sep 17 00:00:00 2001 From: SushiTee Date: Sun, 10 Jul 2011 22:16:16 +0200 Subject: added grid to editor --- src/game/editor/editor.cpp | 173 ++++++++++++++++++++++++++++++++++++++++++--- src/game/editor/editor.h | 10 +++ 2 files changed, 173 insertions(+), 10 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 907552dc..94a5d837 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -466,6 +466,49 @@ int CEditor::DoButton_ButtonDec(const void *pID, const char *pText, int Checked, return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip); } +void CEditor::RenderGrid(CLayerGroup *pGroup) +{ + if(!m_GridActive) + return; + + float aGroupPoints[4]; + pGroup->Mapping(aGroupPoints); + + float w = UI()->Screen()->w; + float h = UI()->Screen()->h; + + int LineDistance = GetLineDistance(); + + int XOffset = aGroupPoints[0]/LineDistance; + int YOffset = aGroupPoints[1]/LineDistance; + int XGridOffset = XOffset % m_GridFactor; + int YGridOffset = YOffset % m_GridFactor; + + Graphics()->TextureSet(-1); + Graphics()->LinesBegin(); + + for(int i = 0; i < (int)w; i++) + { + if((i+YGridOffset) % m_GridFactor == 0) + Graphics()->SetColor(1.0f, 0.3f, 0.3f, 0.3f); + else + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.15f); + + IGraphics::CLineItem Line = IGraphics::CLineItem(LineDistance*XOffset, LineDistance*i+LineDistance*YOffset, w+aGroupPoints[2], LineDistance*i+LineDistance*YOffset); + Graphics()->LinesDraw(&Line, 1); + + if((i+XGridOffset) % m_GridFactor == 0) + Graphics()->SetColor(1.0f, 0.3f, 0.3f, 0.3f); + else + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.15f); + + Line = IGraphics::CLineItem(LineDistance*i+LineDistance*XOffset, LineDistance*YOffset, LineDistance*i+LineDistance*XOffset, h+aGroupPoints[3]); + Graphics()->LinesDraw(&Line, 1); + } + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); + Graphics()->LinesEnd(); +} + void CEditor::RenderBackground(CUIRect View, int Texture, float Size, float Brightness) { Graphics()->TextureSet(Texture); @@ -857,6 +900,41 @@ void CEditor::DoToolbar(CUIRect ToolBar) m_WorldOffsetX = 0; m_WorldOffsetY = 0; } + + TB_Bottom.VSplitLeft(5.0f, 0, &TB_Bottom); + + // grid button + TB_Bottom.VSplitLeft(50.0f, &Button, &TB_Bottom); + static int s_GridButton = 0; + if(DoButton_Editor(&s_GridButton, "Grid", m_GridActive, &Button, 0, "Toggle Grid")) + { + m_GridActive = !m_GridActive; + } + + TB_Bottom.VSplitLeft(30.0f, 0, &TB_Bottom); + + // grid zoom + TB_Bottom.VSplitLeft(30.0f, &Button, &TB_Bottom); + static int s_GridIncreaseButton = 0; + if(DoButton_Ex(&s_GridIncreaseButton, "G-", 0, &Button, 0, "Decrease grid", CUI::CORNER_L)) + { + if(m_GridFactor > 1) + m_GridFactor--; + } + + TB_Bottom.VSplitLeft(30.0f, &Button, &TB_Bottom); + static int s_GridNormalButton = 0; + if(DoButton_Ex(&s_GridNormalButton, "1", 0, &Button, 0, "Normal grid", 0)) + m_GridFactor = 1; + + TB_Bottom.VSplitLeft(30.0f, &Button, &TB_Bottom); + + static int s_GridDecreaseButton = 0; + if(DoButton_Ex(&s_GridDecreaseButton, "G+", 0, &Button, 0, "Increase grid", CUI::CORNER_R)) + { + if(m_GridFactor < 15) + m_GridFactor++; + } } static void Rotate(CPoint *pCenter, CPoint *pPoint, float Rotation) @@ -916,10 +994,41 @@ void CEditor::DoQuad(CQuad *q, int Index) else if(s_Operation == OP_MOVE_ALL) { // move all points including pivot - for(int v = 0; v < 5; v++) + if(m_GridActive) + { + int LineDistance = GetLineDistance(); + + float x = 0.0f; + float y = 0.0f; + if(wx >= 0) + x = (int)((wx+(LineDistance/2)*m_GridFactor)/(LineDistance*m_GridFactor)) * (LineDistance*m_GridFactor); + else + x = (int)((wx-(LineDistance/2)*m_GridFactor)/(LineDistance*m_GridFactor)) * (LineDistance*m_GridFactor); + if(wy >= 0) + 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; + q->m_aPoints[v].y += DiffY; + } + } + else { - q->m_aPoints[v].x += f2fx(wx-s_LastWx); - q->m_aPoints[v].y += f2fx(wy-s_LastWy); + for(int v = 0; v < 5; v++) + { + q->m_aPoints[v].x += f2fx(wx-s_LastWx); + q->m_aPoints[v].y += f2fx(wy-s_LastWy); + } } } else if(s_Operation == OP_ROTATE) @@ -1050,12 +1159,37 @@ void CEditor::DoQuadPoint(CQuad *pQuad, int QuadIndex, int V) { if(s_Operation == OP_MOVEPOINT) { - for(int m = 0; m < 4; m++) - if(m_SelectedPoints&(1<m_aPoints[m].x += f2fx(dx); - pQuad->m_aPoints[m].y += f2fx(dy); - } + if(m_GridActive) + { + for(int m = 0; m < 4; m++) + if(m_SelectedPoints&(1<= 0) + x = (int)((wx+(LineDistance/2)*m_GridFactor)/(LineDistance*m_GridFactor)) * (LineDistance*m_GridFactor); + else + x = (int)((wx-(LineDistance/2)*m_GridFactor)/(LineDistance*m_GridFactor)) * (LineDistance*m_GridFactor); + if(wy >= 0) + 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); + + pQuad->m_aPoints[m].x = f2fx(x); + pQuad->m_aPoints[m].y = f2fx(y); + } + } + else + { + for(int m = 0; m < 4; m++) + if(m_SelectedPoints&(1<m_aPoints[m].x += f2fx(dx); + pQuad->m_aPoints[m].y += f2fx(dy); + } + } } else if(s_Operation == OP_MOVEUV) { @@ -1248,6 +1382,8 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) { g->MapScreen(); + RenderGrid(g); + for(int i = 0; i < NumEditLayers; i++) { if(pEditLayers[i]->m_Type != LAYERTYPE_TILES) @@ -3154,7 +3290,6 @@ void CEditor::Render() Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } - } void CEditor::Reset(bool CreateDefault) @@ -3192,6 +3327,24 @@ void CEditor::Reset(bool CreateDefault) m_Map.m_Modified = false; } +int CEditor::GetLineDistance() +{ + int LineDistance = 512; + + if(m_ZoomLevel <= 100) + LineDistance = 16; + else if(m_ZoomLevel <= 250) + LineDistance = 32; + else if(m_ZoomLevel <= 450) + LineDistance = 64; + else if(m_ZoomLevel <= 850) + LineDistance = 128; + else if(m_ZoomLevel <= 1550) + LineDistance = 256; + + return LineDistance; +} + void CEditorMap::DeleteEnvelope(int Index) { if(Index < 0 || Index >= m_lEnvelopes.size()) diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 353b0774..92ec7b2b 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -475,6 +475,9 @@ public: m_Dialog = 0; m_pTooltip = 0; + m_GridActive = false; + m_GridFactor = 1; + m_aFileName[0] = 0; m_aFileSaveName[0] = 0; m_ValidSaveFilename = false; @@ -556,6 +559,9 @@ public: int m_Dialog; const char *m_pTooltip; + bool m_GridActive; + int m_GridFactor; + char m_aFileName[512]; char m_aFileSaveName[512]; bool m_ValidSaveFilename; @@ -674,6 +680,8 @@ public: void RenderBackground(CUIRect View, int Texture, float Size, float Brightness); + void RenderGrid(CLayerGroup *pGroup); + void UiInvokePopupMenu(void *pID, int Flags, float X, float Y, float W, float H, int (*pfnFunc)(CEditor *pEditor, CUIRect Rect), void *pExtra=0); void UiDoPopupMenu(); @@ -742,6 +750,8 @@ public: int Length = pEnd > pExtractedName ? min(BufferSize, (int)(pEnd-pExtractedName+1)) : BufferSize; str_copy(pName, pExtractedName, Length); } + + int GetLineDistance(); }; // make sure to inline this function -- cgit 1.4.1 From 4d87e9932c33e30eed15ad661039c0400c821051 Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 11 Jul 2011 12:34:17 +0200 Subject: added Portuguese translation by HeroiAmarelo and renamed existing one to Brazilian Portuguese --- data/languages/brazilian_portuguese.txt | 679 ++++++++++++++++++++++++++++++++ data/languages/index.txt | 3 + data/languages/portuguese.txt | 287 +++++++------- data/languages/russian.txt | 3 +- data/languages/spanish.txt | 37 +- 5 files changed, 847 insertions(+), 162 deletions(-) create mode 100644 data/languages/brazilian_portuguese.txt diff --git a/data/languages/brazilian_portuguese.txt b/data/languages/brazilian_portuguese.txt new file mode 100644 index 00000000..6513a31f --- /dev/null +++ b/data/languages/brazilian_portuguese.txt @@ -0,0 +1,679 @@ + +##### translated strings ##### + +%d Bytes +== %d Bytes + +%d of %d servers, %d players +== %d de %d Servidores, %d Jogadores + +%d%% loaded +== %d%% Carregado + +%ds left +== Faltam %ds + +%i minute left +== Falta %i Minuto + +%i minutes left +== Faltam %i Minutos + +%i second left +== Falta %i Segundo + +%i seconds left +== Faltam %i Segundos + +%s wins! +== %s Vence! + +-Page %d- +== -Página %d- + +Abort +== Cancelar + +Add +== Adicionar + +Add Friend +== Adicionar Amigo + +Address +== Endereço + +All +== Todos + +Alpha +== Alpha + +Always show name plates +== Sempre mostrar apelidos + +Are you sure that you want to delete the demo? +== Tem certeza que deseja deletar o Demo? + +Are you sure that you want to quit? +== Você tem certeza que deseja sair? + +Are you sure that you want to remove the player from your friends list? +== Tem certeza que deseja remover o Jogador de sua Lista de Amigos? + +As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. +== Como esta é a primeira vez que você abre o jogo, por favor, coloque seu apelido abaixo. É recomendado que você verifique as configurações e então ajuste-as para suas preferências antes de entrar em um servidor. + +Automatically record demos +== Gravar demos automaticamente + +Automatically take game over screenshot +== Capturar tela final de jogo automaticamente + +Blue team +== Time Azul + +Blue team wins! +== Vitória do Time Azul! + +Body +== Corpo + +Call vote +== Votar + +Change settings +== Mudar Configurações + +Chat +== Chat + +Clan +== Clã + +Client +== Cliente + +Close +== Fechar + +Compatible version +== Versão Compatível + +Connect +== Conectar + +Connecting to +== Conectando a + +Connection Problems... +== Problemas de Conexão... + +Console +== Console + +Controls +== Controles + +Count players only +== Contar apenas Jogadores + +Country +== País + +Crc: +== Crc: + +Created: +== Criado: + +Current +== Atual + +Current version: %s +== Versão atual: %s + +Custom colors +== Cores Personalizadas + +Delete +== Deletar + +Delete demo +== Deletar Demo + +Demo details +== Detalhes do Demo + +Demofile: %s +== Demo: %s + +Demos +== Demos + +Disconnect +== Desconectar + +Disconnected +== Desconectado + +Display Modes +== Modos de exibição + +Downloading map +== Baixando mapa + +Draw! +== Empate! + +Dynamic Camera +== Câmera Dinâmica + +Emoticon +== Emoticon + +Enter +== Entrar + +Error +== Erro + +Error loading demo +== Erro ao carregar Demo + +FSAA samples +== Amostras FSAA + +Favorite +== Favorito + +Favorites +== Favoritos + +Feet +== Pés + +Filter +== Filtro + +Fire +== Atirar + +Folder +== Pasta + +Force vote +== Forçar Votação + +Free-View +== Visualização Livre + +Friends +== Amigos + +Fullscreen +== Tela Cheia + +Game +== Jogo + +Game info +== Jogo + +Game over +== Fim do Jogo + +Game type +== Tipo de Jogo + +Game types: +== Tipos de Jogo: + +General +== Geral + +Graphics +== Gráficos + +Grenade +== Granada + +Hammer +== Martelo + +Has people playing +== Há pessoas jogando + +High Detail +== Mostrar Detalhes + +Hook +== Gancho + +Host address +== Endereço do Domínio + +Hue +== Matiz + +Info +== Informações + +Internet +== Internet + +Invalid Demo +== Demo Inválido + +Join blue +== Time Azul + +Join game +== Entrar no Jogo + +Join red +== Time Vermelho + +Jump +== Pular + +Kick player +== Expulsar Jogador + +LAN +== LAN + +Language +== Idioma + +Length: +== Comprimento: + +Lht. +== Brilho. + +Loading +== Carregando + +MOTD +== MOTD + +Map +== Mapa + +Map: +== Mapa: + +Max Screenshots +== Máximo de capturas de tela + +Max demos +== Máximo de Demos + +Maximum ping: +== Ping Máximo: + +Miscellaneous +== Diversos + +Mouse sens. +== Sens. do Mouse + +Move left +== Andar para Esquerda + +Move player to spectators +== Mover jogador para Espectadores + +Move right +== Andar para Direita + +Movement +== Movimento + +Mute when not active +== Silenciar quando Inativo + +Name +== Nome + +Name plates size +== Tamanho dos Apelidos + +Netversion: +== Netversion + +New name: +== Novo nome: + +News +== Novidades + +Next weapon +== Próxima arma + +Nickname +== Apelido + +No +== Não + +No password +== Sem Senha + +No servers found +== Nenhum servidor encontrado + +No servers match your filter criteria +== Nenhum servidor corresponde aos critérios do filtro + +Ok +== Ok + +Open +== Abrir + +Parent Folder +== Diretório Principal + +Password +== Senha + +Password incorrect +== Senha Incorreta + +Ping +== Ping + +Pistol +== Pistola + +Play +== Assistir + +Play background music +== Tocar Música de Fundo + +Player +== Jogador + +Player country: +== País do Jogador: + +Player options +== Opções do Jogador + +Players +== Jogadores + +Please balance teams! +== Favor balancear os Times! + +Prev. weapon +== Arma anterior + +Quality Textures +== Texturas de Qualidade + +Quick search: +== Pesquisa rápida: + +Quit +== Sair + +Quit anyway? +== Sair mesmo assim? + +REC %3d:%02d +== REC %3d:%02d + +Reason: +== Motivo: + +Record demo +== Gravar Demo + +Red team +== Time Vermelho + +Red team wins! +== Vitória do Time Vermelho! + +Refresh +== Atualizar + +Refreshing master servers +== Atualizando servidores mestres + +Remote console +== Console remoto + +Remove +== Deletar + +Remove friend +== Deletar Amigo + +Rename +== Renomear + +Rename demo +== Renomear Demo + +Reset filter +== Resetar Filtro + +Reset to defaults +== Configurações Padrão + +Rifle +== Laser + +Round +== Rodada + +Sample rate +== Frequência do Som + +Sat. +== Saturação. + +Score +== Pontos + +Score board +== Placar + +Score limit +== Pontuação Máxima + +Scoreboard +== Placar + +Screenshot +== Capturar Tela + +Server address: +== Endereço do Servidor: + +Server details +== Detalhes do Servidor + +Server filter +== Filtro de Servidores + +Server info +== Servidor + +Server not full +== Servidor Não Lotado + +Settings +== Configurações + +Shotgun +== Espingarda + +Show chat +== Mostrar Chat + +Show friends only +== Mostrar Apenas Amigos + +Show ingame HUD +== Mostrar Display do Jogo + +Show name plates +== Mostrar Apelidos + +Show only supported +== Mostrar apenas o suportado + +Size: +== Tamanho: + +Skins +== Skins + +Sound +== Som + +Sound error +== Erro de Som + +Sound volume +== Volume do Som + +Spectate +== Observar + +Spectate next +== Observar próximo + +Spectate previous +== Observar anterior + +Spectator mode +== Modo Espectador + +Spectators +== Espectadores + +Standard gametype +== Tipo de Jogo Padrão + +Standard map +== Mapa Padrão + +Stop record +== Parar a Gravação + +Strict gametype filter +== Filtrar tipo Exato de Jogo + +Sudden Death +== Morte Súbita + +Switch weapon on pickup +== Mudar arma ao pegá-las + +Team +== Time + +Team chat +== Chat do Time + +Teeworlds %s is out! Download it at www.teeworlds.com! +== Teeworlds %s está pronto! Faça o Download em www.teeworlds.com! + +Texture Compression +== Compressão da Textura + +The audio device couldn't be initialised. +== O Dispositivo de áudio não pôde ser inicializado. + +The server is running a non-standard tuning on a pure game type. +== O Servidor está sendo executado com ajustes diferentes de seu Padrão Oficial de tipo de jogo. + +There's an unsaved map in the editor, you might want to save it before you quit the game. +== Existe um Mapa não salvo no editor, você deve querer salvá-lo antes de sair do jogo. + +Time limit +== Limite de Tempo + +Time limit: %d min +== Limite de tempo: %d Minutos + +Try again +== Tente Novamente + +Type +== Tipo + +Type: +== Tipo: + +UI Color +== Cor do Menu + +Unable to delete the demo +== Não é possível deletar Demo + +Unable to rename the demo +== Não é possível renomear Demo + +Use sounds +== Usar Sons + +Use team colors for name plates +== Usar cores dos times em Apelidos + +V-Sync +== V-Sync + +Version +== Versão + +Version: +== Versão + +Vote command: +== Comando para Votar: + +Vote description: +== Descrição da Votação: + +Vote no +== Vote Não + +Vote yes +== Vote Sim + +Voting +== Votação + +Warmup +== Aquecimento + +Weapon +== Arma + +Welcome to Teeworlds +== Bem-Vindo ao Teeworlds! + +Yes +== Sim + +You must restart the game for all settings to take effect. +== Você deve reiniciar o jogo para que todas as alterações tenham efeito. + +Your skin +== Sua Skin + +no limit +== Sem Limite + +##### needs translation ##### + +##### old translations ##### + diff --git a/data/languages/index.txt b/data/languages/index.txt index fa5862c9..3e8d9f91 100644 --- a/data/languages/index.txt +++ b/data/languages/index.txt @@ -4,6 +4,9 @@ bosnian == Bosanski +brazilian_portuguese +== Português brasileiro + bulgarian == Български diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index cbfdab89..8d830608 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -1,31 +1,32 @@ + ##### translated strings ##### %d Bytes == %d Bytes %d of %d servers, %d players -== %d de %d Servidores, %d Jogadores +== %d de %d servidores, %d jogadores %d%% loaded -== %d%% Carregado +== %d%% A Carregar %ds left -== Faltam %ds +== faltam %ds %i minute left -== Falta %i Minuto +== falta %i minuto %i minutes left -== Faltam %i Minutos +== faltam %i minutos %i second left -== Falta %i Segundo +== falta %i segundo %i seconds left -== Faltam %i Segundos +== faltam %i segundos %s wins! -== %s Vence! +== %s ganhou! -Page %d- == -Página %d- @@ -49,46 +50,46 @@ Alpha == Alpha Always show name plates -== Sempre mostrar apelidos +== Mostrar sempre os nicks Are you sure that you want to delete the demo? -== Tem certeza que deseja deletar o Demo? +== Tens a certeza que queres Eliminar a demo? Are you sure that you want to quit? -== Você tem certeza que deseja sair? +== Queres mesmo sair? Are you sure that you want to remove the player from your friends list? -== Tem certeza que deseja remover o Jogador de sua Lista de Amigos? +== Queres mesmo apaga-lo da tua lista de amigos? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Como esta é a primeira vez que você abre o jogo, por favor, coloque seu apelido abaixo. É recomendado que você verifique as configurações e então ajuste-as para suas preferências antes de entrar em um servidor. +== Olá! Pelos vistos é a primeira vez que inicias o jogo, por isso escolhe um Nick Name para ti! Automatically record demos -== Gravar demos automaticamente +== Gravar demos Automaticamente Automatically take game over screenshot -== Capturar tela final de jogo automaticamente +== Tirar screenshot's Automaticamente Blue team -== Time Azul +== Equipa azul Blue team wins! -== Vitória do Time Azul! +== A Equipa azul ganhou! Body == Corpo Call vote -== Votar +== Votação Change settings -== Mudar Configurações +== Mudar configurações Chat -== Chat +== Conversa Clan -== Clã +== Clan Client == Cliente @@ -97,25 +98,25 @@ Close == Fechar Compatible version -== Versão Compatível +== Versão compatível Connect == Conectar Connecting to -== Conectando a +== A Conectar a Connection Problems... -== Problemas de Conexão... +== Problemas na conecção! Console == Console Controls -== Controles +== Controlos Count players only -== Contar apenas Jogadores +== Só contar jogadores Country == País @@ -127,22 +128,22 @@ Created: == Criado: Current -== Atual +== Actualmente Current version: %s -== Versão atual: %s +== Versão actual : %s Custom colors -== Cores Personalizadas +== Cores personalizadas Delete -== Deletar +== Eliminar Delete demo -== Deletar Demo +== Eliminar demo Demo details -== Detalhes do Demo +== Detalhes da demo Demofile: %s == Demo: %s @@ -160,13 +161,13 @@ Display Modes == Modos de exibição Downloading map -== Baixando mapa +== A fazer download do mapa... Draw! == Empate! Dynamic Camera -== Câmera Dinâmica +== Câmera dinâmica Emoticon == Emoticon @@ -178,7 +179,7 @@ Error == Erro Error loading demo -== Erro ao carregar Demo +== Erro a carregar a demo FSAA samples == Amostras FSAA @@ -196,37 +197,37 @@ Filter == Filtro Fire -== Atirar +== Disparar Folder == Pasta Force vote -== Forçar Votação +== Forçar Free-View -== Visualização Livre +== Vista Livre Friends == Amigos Fullscreen -== Tela Cheia +== Fullscreen (Ecrã inteiro) Game == Jogo Game info -== Jogo +== Info sobre o jogo Game over -== Fim do Jogo +== Fim de Jogo Game type -== Tipo de Jogo +== Tipo de jogo Game types: -== Tipos de Jogo: +== Tipos de jogo: General == Geral @@ -241,55 +242,55 @@ Hammer == Martelo Has people playing -== Há pessoas jogando +== Há gente a jogar High Detail -== Mostrar Detalhes +== Mais detalhes (HD) Hook == Gancho Host address -== Endereço do Domínio +== Direcção do Host Hue == Matiz Info -== Informações +== Info. Internet == Internet Invalid Demo -== Demo Inválido +== Demo inválida Join blue -== Time Azul +== Juntar - Azuis Join game -== Entrar no Jogo +== Entrar no jogo Join red -== Time Vermelho +== J. Vermelhos Jump -== Pular +== Saltar Kick player -== Expulsar Jogador +== Expulsar jogador LAN == LAN Language -== Idioma +== Língua Length: -== Comprimento: +== Longitude: Lht. -== Brilho. +== Luz Loading == Carregando @@ -304,40 +305,40 @@ Map: == Mapa: Max Screenshots -== Máximo de capturas de tela +== Máx. de Capturas de Tela Max demos -== Máximo de Demos +== Demos maximas Maximum ping: -== Ping Máximo: +== Ping máximo: Miscellaneous == Diversos Mouse sens. -== Sens. do Mouse +== Sens. do rato Move left -== Andar para Esquerda +== Esquerda Move player to spectators -== Mover jogador para Espectadores +== Juntar jogador aos espectadores Move right -== Andar para Direita +== Direita Movement == Movimento Mute when not active -== Silenciar quando Inativo +== Silencíar os jogadores inactivos Name == Nome Name plates size -== Tamanho dos Apelidos +== Caracteres maximos nos nicks Netversion: == Netversion @@ -346,40 +347,40 @@ New name: == Novo nome: News -== Novidades +== Notícia Next weapon == Próxima arma Nickname -== Apelido +== Nick No == Não No password -== Sem Senha +== Sem password No servers found -== Nenhum servidor encontrado +== Nenhum servidor encontrado. No servers match your filter criteria -== Nenhum servidor corresponde aos critérios do filtro +== Não há servidores que correspondam às definições de procura. Ok -== Ok +== Aceitar Open == Abrir Parent Folder -== Diretório Principal +== Pasta superior Password -== Senha +== Password Password incorrect -== Senha Incorreta +== Password errada! Ping == Ping @@ -388,25 +389,25 @@ Pistol == Pistola Play -== Assistir +== Ver Play background music -== Tocar Música de Fundo +== Tocar a música de fundo Player == Jogador Player country: -== País do Jogador: +== País do jogador Player options -== Opções do Jogador +== Opções do jogador Players == Jogadores Please balance teams! -== Favor balancear os Times! +== Equilibrem as equipas! Prev. weapon == Arma anterior @@ -415,13 +416,13 @@ Quality Textures == Texturas de Qualidade Quick search: -== Pesquisa rápida: +== Busca rápida: Quit == Sair Quit anyway? -== Sair mesmo assim? +== Sair na mesma? REC %3d:%02d == REC %3d:%02d @@ -430,103 +431,103 @@ Reason: == Motivo: Record demo -== Gravar Demo +== Gravar uma demo Red team -== Time Vermelho +== Equipa vermelha Red team wins! -== Vitória do Time Vermelho! +== Ganhou a equipa vermelha! Refresh -== Atualizar +== Actualizar Refreshing master servers -== Atualizando servidores mestres +== A Actualizar servidores Remote console -== Console remoto +== Remote console Remove -== Deletar +== Eliminar Remove friend -== Deletar Amigo +== Deixar de ser amigo Rename == Renomear Rename demo -== Renomear Demo +== Renomear demo Reset filter -== Resetar Filtro +== Reiniciar Fitro Reset to defaults -== Configurações Padrão +== Por como defeito Rifle == Laser Round -== Rodada +== Ronda Sample rate -== Frequência do Som +== Frequencia de rate Sat. -== Saturação. +== Sat. Score == Pontos Score board -== Placar +== Tabela de Pontos Score limit -== Pontuação Máxima +== Pontuação Máx. Scoreboard -== Placar +== Pontuação Screenshot -== Capturar Tela +== Screenshot Server address: -== Endereço do Servidor: +== Direção do servidor: Server details -== Detalhes do Servidor +== Detalhes do servidor Server filter -== Filtro de Servidores +== Filtro de servidores Server info -== Servidor +== Info de servidor Server not full -== Servidor Não Lotado +== Não está cheio Settings -== Configurações +== Config. Shotgun == Espingarda Show chat -== Mostrar Chat +== Mostrar chat Show friends only -== Mostrar Apenas Amigos +== Mostrar amigos Show ingame HUD -== Mostrar Display do Jogo +== Mostrar HUD do jogo Show name plates -== Mostrar Apelidos +== Mostrar nick's Show only supported -== Mostrar apenas o suportado +== Mostrar apenas suportado Size: == Tamanho: @@ -538,10 +539,10 @@ Sound == Som Sound error -== Erro de Som +== Erro no som! Sound volume -== Volume do Som +== Volume Spectate == Observar @@ -553,58 +554,58 @@ Spectate previous == Observar anterior Spectator mode -== Modo Espectador +== Modo espectador Spectators == Espectadores Standard gametype -== Tipo de Jogo Padrão +== Tipo de jogo normal Standard map -== Mapa Padrão +== Mapa normal Stop record -== Parar a Gravação +== Parar de gravar Strict gametype filter -== Filtrar tipo Exato de Jogo +== Tipo de jogo especifico Sudden Death -== Morte Súbita +== Morte súbita Switch weapon on pickup -== Mudar arma ao pegá-las +== Mudar de arma ao agarrar Team -== Time +== Equipa Team chat -== Chat do Time +== Chat de equipa Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s está pronto! Faça o Download em www.teeworlds.com! +== Teeworlds %s já saiu! Download em www.teeworlds.com! Texture Compression -== Compressão da Textura +== Compressão de Textura The audio device couldn't be initialised. -== O Dispositivo de áudio não pôde ser inicializado. +== O dispositivo de som não pode ser iniciado. The server is running a non-standard tuning on a pure game type. -== O Servidor está sendo executado com ajustes diferentes de seu Padrão Oficial de tipo de jogo. +== O servidor está a usar um tipo de jogo não oficial. There's an unsaved map in the editor, you might want to save it before you quit the game. -== Existe um Mapa não salvo no editor, você deve querer salvá-lo antes de sair do jogo. +== O mapa que editas-te não foi gravado. Queres gravar antes de sair? Time limit -== Limite de Tempo +== Tempo máx. Time limit: %d min -== Limite de tempo: %d Minutos +== Limite de tempo: %d min Try again -== Tente Novamente +== Tenta outra vez Type == Tipo @@ -613,19 +614,19 @@ Type: == Tipo: UI Color -== Cor do Menu +== Cor do menu Unable to delete the demo -== Não é possível deletar Demo +== Não podes eliminar a demo Unable to rename the demo -== Não é possível renomear Demo +== Impossivel de renomear a demo Use sounds -== Usar Sons +== Usar sons Use team colors for name plates -== Usar cores dos times em Apelidos +== Usar cores dos nicks com a cor da equipa V-Sync == V-Sync @@ -637,19 +638,19 @@ Version: == Versão Vote command: -== Comando para Votar: +== Comando: Vote description: -== Descrição da Votação: +== Descrição de votação: Vote no -== Vote Não +== Votar não Vote yes -== Vote Sim +== Votar sim Voting -== Votação +== A votar Warmup == Aquecimento @@ -658,19 +659,19 @@ Weapon == Arma Welcome to Teeworlds -== Bem-Vindo ao Teeworlds! +== Bem-vindo ao Teeworlds! Yes == Sim You must restart the game for all settings to take effect. -== Você deve reiniciar o jogo para que todas as alterações tenham efeito. +== Para que as configurações sejam efectuadas deves Reiniciar o jogo. Your skin -== Sua Skin +== A tua skin no limit -== Sem Limite +== sem limite ##### needs translation ##### diff --git a/data/languages/russian.txt b/data/languages/russian.txt index 32215ebc..329f4a69 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes @@ -674,5 +675,5 @@ no limit ##### needs translation ##### +##### old translations ##### -##### old translations ##### \ No newline at end of file diff --git a/data/languages/spanish.txt b/data/languages/spanish.txt index 42105d43..77dc07c7 100644 --- a/data/languages/spanish.txt +++ b/data/languages/spanish.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes @@ -144,6 +145,9 @@ Delete demo Demo details == Detellades demo +Demofile: %s +== Archivo Demo: %s + Demos == Demos @@ -387,9 +391,15 @@ Pistol Play == Asistir +Play background music +== Reproducir música de fondo + Player == Jugador +Player country: +== Tú Pais + Player options == Opciones de Jugador @@ -537,6 +547,12 @@ Sound volume Spectate == Observar +Spectate next +== Observar siguiente + +Spectate previous +== Observar anterior + Spectator mode == Modo espectador @@ -552,6 +568,9 @@ Standard map Stop record == Parar grabación +Strict gametype filter +== Filtro estricto gametype + Sudden Death == Muerte Súbita @@ -656,23 +675,5 @@ no limit ##### needs translation ##### -Demofile: %s -== Archivo Demo: %s - -Play background music -== Reproducir música de fondo - -Player country: -== Tú Pais - -Spectate next -== Observar siguiente - -Spectate previous -== Observar anterior - -Strict gametype filter -== Filtro estricto gametype - ##### old translations ##### -- cgit 1.4.1 From 38202d97366539cba27ca9f8113288c1c7942885 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 12 Jul 2011 20:23:42 +0200 Subject: added country flags --- data/countryflags/AD.png | Bin 0 -> 2741 bytes data/countryflags/AE.png | Bin 0 -> 816 bytes data/countryflags/AF.png | Bin 0 -> 2631 bytes data/countryflags/AG.png | Bin 0 -> 2161 bytes data/countryflags/AI.png | Bin 0 -> 2544 bytes data/countryflags/AL.png | Bin 0 -> 2347 bytes data/countryflags/AM.png | Bin 0 -> 740 bytes data/countryflags/AO.png | Bin 0 -> 1739 bytes data/countryflags/AR.png | Bin 1571 -> 1519 bytes data/countryflags/AS.png | Bin 0 -> 4005 bytes data/countryflags/AT.png | Bin 1072 -> 798 bytes data/countryflags/AU.png | Bin 3842 -> 2472 bytes data/countryflags/AW.png | Bin 0 -> 1280 bytes data/countryflags/AX.png | Bin 0 -> 985 bytes data/countryflags/AZ.png | Bin 0 -> 1288 bytes data/countryflags/BA.png | Bin 2868 -> 2175 bytes data/countryflags/BB.png | Bin 0 -> 1354 bytes data/countryflags/BD.png | Bin 0 -> 1145 bytes data/countryflags/BE.png | Bin 879 -> 678 bytes data/countryflags/BF.png | Bin 0 -> 1073 bytes data/countryflags/BG.png | Bin 1006 -> 789 bytes data/countryflags/BH.png | Bin 0 -> 1493 bytes data/countryflags/BI.png | Bin 0 -> 2643 bytes data/countryflags/BJ.png | Bin 0 -> 851 bytes data/countryflags/BL.png | Bin 0 -> 6881 bytes data/countryflags/BM.png | Bin 0 -> 3329 bytes data/countryflags/BN.png | Bin 0 -> 3910 bytes data/countryflags/BO.png | Bin 0 -> 1674 bytes data/countryflags/BR.png | Bin 3905 -> 2682 bytes data/countryflags/BS.png | Bin 0 -> 1216 bytes data/countryflags/BT.png | Bin 0 -> 4193 bytes data/countryflags/BW.png | Bin 0 -> 719 bytes data/countryflags/BY.png | Bin 2728 -> 1869 bytes data/countryflags/BZ.png | Bin 0 -> 5185 bytes data/countryflags/CA.png | Bin 1885 -> 1436 bytes data/countryflags/CC.png | Bin 0 -> 2056 bytes data/countryflags/CD.png | Bin 0 -> 2868 bytes data/countryflags/CF.png | Bin 0 -> 1148 bytes data/countryflags/CG.png | Bin 0 -> 1580 bytes data/countryflags/CH.png | Bin 1099 -> 896 bytes data/countryflags/CI.png | Bin 0 -> 818 bytes data/countryflags/CK.png | Bin 0 -> 3372 bytes data/countryflags/CL.png | Bin 1422 -> 984 bytes data/countryflags/CM.png | Bin 0 -> 1104 bytes data/countryflags/CN.png | Bin 1720 -> 1331 bytes data/countryflags/CO.png | Bin 993 -> 784 bytes data/countryflags/CR.png | Bin 0 -> 1531 bytes data/countryflags/CU.png | Bin 0 -> 1632 bytes data/countryflags/CV.png | Bin 0 -> 1668 bytes data/countryflags/CW.png | Bin 0 -> 1138 bytes data/countryflags/CX.png | Bin 0 -> 2560 bytes data/countryflags/CY.png | Bin 0 -> 1905 bytes data/countryflags/CZ.png | Bin 1815 -> 962 bytes data/countryflags/DE.png | Bin 863 -> 666 bytes data/countryflags/DJ.png | Bin 0 -> 1758 bytes data/countryflags/DK.png | Bin 1207 -> 863 bytes data/countryflags/DM.png | Bin 0 -> 2237 bytes data/countryflags/DO.png | Bin 0 -> 1646 bytes data/countryflags/DZ.png | Bin 0 -> 1605 bytes data/countryflags/EC.png | Bin 0 -> 2589 bytes data/countryflags/EE.png | Bin 887 -> 632 bytes data/countryflags/EG.png | Bin 1662 -> 1406 bytes data/countryflags/EH.png | Bin 0 -> 1516 bytes data/countryflags/ER.png | Bin 0 -> 3335 bytes data/countryflags/ES.png | Bin 2406 -> 2174 bytes data/countryflags/ET.png | Bin 0 -> 2587 bytes data/countryflags/FI.png | Bin 1071 -> 832 bytes data/countryflags/FJ.png | Bin 0 -> 3222 bytes data/countryflags/FK.png | Bin 0 -> 4080 bytes data/countryflags/FM.png | Bin 0 -> 1434 bytes data/countryflags/FO.png | Bin 0 -> 994 bytes data/countryflags/FR.png | Bin 1037 -> 814 bytes data/countryflags/GA.png | Bin 0 -> 857 bytes data/countryflags/GB.png | Bin 4786 -> 2870 bytes data/countryflags/GD.png | Bin 0 -> 2669 bytes data/countryflags/GE.png | Bin 0 -> 1595 bytes data/countryflags/GF.png | Bin 0 -> 1637 bytes data/countryflags/GG.png | Bin 0 -> 1143 bytes data/countryflags/GH.png | Bin 0 -> 1152 bytes data/countryflags/GI.png | Bin 0 -> 2466 bytes data/countryflags/GL.png | Bin 0 -> 1130 bytes data/countryflags/GM.png | Bin 0 -> 789 bytes data/countryflags/GN.png | Bin 0 -> 822 bytes data/countryflags/GP.png | Bin 0 -> 1180 bytes data/countryflags/GQ.png | Bin 0 -> 1599 bytes data/countryflags/GR.png | Bin 1439 -> 1011 bytes data/countryflags/GS.png | Bin 0 -> 4830 bytes data/countryflags/GT.png | Bin 0 -> 1910 bytes data/countryflags/GU.png | Bin 0 -> 2242 bytes data/countryflags/GW.png | Bin 0 -> 1138 bytes data/countryflags/GY.png | Bin 0 -> 2993 bytes data/countryflags/HK.png | Bin 0 -> 2097 bytes data/countryflags/HN.png | Bin 0 -> 1224 bytes data/countryflags/HR.png | Bin 2614 -> 2320 bytes data/countryflags/HT.png | Bin 0 -> 1577 bytes data/countryflags/HU.png | Bin 1027 -> 838 bytes data/countryflags/ID.png | Bin 1017 -> 787 bytes data/countryflags/IE.png | Bin 0 -> 847 bytes data/countryflags/IL.png | Bin 2110 -> 1565 bytes data/countryflags/IM.png | Bin 0 -> 2053 bytes data/countryflags/IN.png | Bin 1841 -> 1518 bytes data/countryflags/IO.png | Bin 0 -> 7189 bytes data/countryflags/IQ.png | Bin 0 -> 1469 bytes data/countryflags/IR.png | Bin 3227 -> 2604 bytes data/countryflags/IS.png | Bin 0 -> 1017 bytes data/countryflags/IT.png | Bin 1022 -> 861 bytes data/countryflags/JE.png | Bin 0 -> 3269 bytes data/countryflags/JM.png | Bin 0 -> 2407 bytes data/countryflags/JO.png | Bin 0 -> 1048 bytes data/countryflags/JP.png | Bin 0 -> 1397 bytes data/countryflags/KE.png | Bin 0 -> 2149 bytes data/countryflags/KG.png | Bin 0 -> 3085 bytes data/countryflags/KH.png | Bin 0 -> 2424 bytes data/countryflags/KI.png | Bin 0 -> 4268 bytes data/countryflags/KM.png | Bin 0 -> 1804 bytes data/countryflags/KN.png | Bin 0 -> 2524 bytes data/countryflags/KP.png | Bin 0 -> 1618 bytes data/countryflags/KR.png | Bin 0 -> 2860 bytes data/countryflags/KW.png | Bin 0 -> 1119 bytes data/countryflags/KY.png | Bin 0 -> 3989 bytes data/countryflags/KZ.png | Bin 4339 -> 3021 bytes data/countryflags/LA.png | Bin 0 -> 1033 bytes data/countryflags/LB.png | Bin 0 -> 1918 bytes data/countryflags/LC.png | Bin 0 -> 1904 bytes data/countryflags/LI.png | Bin 0 -> 1598 bytes data/countryflags/LK.png | Bin 0 -> 4089 bytes data/countryflags/LR.png | Bin 0 -> 1268 bytes data/countryflags/LS.png | Bin 0 -> 1378 bytes data/countryflags/LT.png | Bin 991 -> 758 bytes data/countryflags/LU.png | Bin 1089 -> 832 bytes data/countryflags/LV.png | Bin 1052 -> 771 bytes data/countryflags/LY.png | Bin 0 -> 634 bytes data/countryflags/MA.png | Bin 0 -> 1667 bytes data/countryflags/MC.png | Bin 0 -> 764 bytes data/countryflags/MD.png | Bin 0 -> 2601 bytes data/countryflags/ME.png | Bin 0 -> 3243 bytes data/countryflags/MF.png | Bin 0 -> 1623 bytes data/countryflags/MG.png | Bin 0 -> 894 bytes data/countryflags/MH.png | Bin 0 -> 3355 bytes data/countryflags/MK.png | Bin 0 -> 2768 bytes data/countryflags/ML.png | Bin 0 -> 832 bytes data/countryflags/MM.png | Bin 0 -> 1550 bytes data/countryflags/MN.png | Bin 0 -> 1718 bytes data/countryflags/MO.png | Bin 0 -> 2064 bytes data/countryflags/MP.png | Bin 0 -> 5386 bytes data/countryflags/MQ.png | Bin 0 -> 3036 bytes data/countryflags/MR.png | Bin 0 -> 1559 bytes data/countryflags/MS.png | Bin 0 -> 2919 bytes data/countryflags/MT.png | Bin 0 -> 1263 bytes data/countryflags/MU.png | Bin 0 -> 843 bytes data/countryflags/MV.png | Bin 0 -> 1140 bytes data/countryflags/MW.png | Bin 0 -> 2357 bytes data/countryflags/MX.png | Bin 2486 -> 2211 bytes data/countryflags/MY.png | Bin 0 -> 2080 bytes data/countryflags/MZ.png | Bin 0 -> 2087 bytes data/countryflags/NA.png | Bin 0 -> 3339 bytes data/countryflags/NC.png | Bin 0 -> 2547 bytes data/countryflags/NE.png | Bin 0 -> 1060 bytes data/countryflags/NF.png | Bin 0 -> 2791 bytes data/countryflags/NG.png | Bin 0 -> 771 bytes data/countryflags/NI.png | Bin 0 -> 1463 bytes data/countryflags/NL.png | Bin 1064 -> 825 bytes data/countryflags/NO.png | Bin 1327 -> 975 bytes data/countryflags/NP.png | Bin 0 -> 2085 bytes data/countryflags/NR.png | Bin 0 -> 1294 bytes data/countryflags/NU.png | Bin 0 -> 2806 bytes data/countryflags/NZ.png | Bin 0 -> 2166 bytes data/countryflags/OM.png | Bin 0 -> 1496 bytes data/countryflags/PA.png | Bin 0 -> 1385 bytes data/countryflags/PE.png | Bin 0 -> 794 bytes data/countryflags/PF.png | Bin 0 -> 1967 bytes data/countryflags/PG.png | Bin 0 -> 2315 bytes data/countryflags/PH.png | Bin 2843 -> 2109 bytes data/countryflags/PK.png | Bin 2180 -> 1638 bytes data/countryflags/PL.png | Bin 988 -> 753 bytes data/countryflags/PM.png | Bin 0 -> 7849 bytes data/countryflags/PN.png | Bin 0 -> 4692 bytes data/countryflags/PR.png | Bin 0 -> 1670 bytes data/countryflags/PT.png | Bin 2940 -> 2653 bytes data/countryflags/PW.png | Bin 0 -> 1375 bytes data/countryflags/PY.png | Bin 0 -> 1584 bytes data/countryflags/QA.png | Bin 0 -> 1193 bytes data/countryflags/RE.png | Bin 0 -> 1816 bytes data/countryflags/RO.png | Bin 1002 -> 805 bytes data/countryflags/RS.png | Bin 3666 -> 3054 bytes data/countryflags/RU.png | Bin 989 -> 719 bytes data/countryflags/RW.png | Bin 0 -> 1557 bytes data/countryflags/SA.png | Bin 3662 -> 2605 bytes data/countryflags/SB.png | Bin 0 -> 2399 bytes data/countryflags/SC.png | Bin 0 -> 2184 bytes data/countryflags/SD.png | Bin 0 -> 1015 bytes data/countryflags/SE.png | Bin 1098 -> 849 bytes data/countryflags/SG.png | Bin 0 -> 1407 bytes data/countryflags/SH.png | Bin 0 -> 3167 bytes data/countryflags/SI.png | Bin 0 -> 1507 bytes data/countryflags/SK.png | Bin 2280 -> 1836 bytes data/countryflags/SL.png | Bin 0 -> 836 bytes data/countryflags/SM.png | Bin 0 -> 2585 bytes data/countryflags/SN.png | Bin 0 -> 1108 bytes data/countryflags/SO.png | Bin 0 -> 1181 bytes data/countryflags/SR.png | Bin 0 -> 1260 bytes data/countryflags/SS.png | Bin 0 -> 1437 bytes data/countryflags/ST.png | Bin 0 -> 1348 bytes data/countryflags/SV.png | Bin 1893 -> 1717 bytes data/countryflags/SX.png | Bin 0 -> 2708 bytes data/countryflags/SY.png | Bin 0 -> 1171 bytes data/countryflags/SZ.png | Bin 0 -> 2458 bytes data/countryflags/TC.png | Bin 0 -> 2398 bytes data/countryflags/TD.png | Bin 0 -> 805 bytes data/countryflags/TF.png | Bin 0 -> 1729 bytes data/countryflags/TG.png | Bin 0 -> 1208 bytes data/countryflags/TH.png | Bin 0 -> 797 bytes data/countryflags/TJ.png | Bin 0 -> 1597 bytes data/countryflags/TK.png | Bin 0 -> 2242 bytes data/countryflags/TL.png | Bin 0 -> 1379 bytes data/countryflags/TM.png | Bin 0 -> 3311 bytes data/countryflags/TN.png | Bin 0 -> 1733 bytes data/countryflags/TO.png | Bin 0 -> 832 bytes data/countryflags/TR.png | Bin 2117 -> 1622 bytes data/countryflags/TT.png | Bin 0 -> 1938 bytes data/countryflags/TV.png | Bin 0 -> 3266 bytes data/countryflags/TW.png | Bin 0 -> 1126 bytes data/countryflags/TZ.png | Bin 0 -> 2300 bytes data/countryflags/UA.png | Bin 938 -> 777 bytes data/countryflags/UG.png | Bin 0 -> 1360 bytes data/countryflags/US.png | Bin 3280 -> 2401 bytes data/countryflags/UY.png | Bin 0 -> 2188 bytes data/countryflags/UZ.png | Bin 0 -> 1385 bytes data/countryflags/VA.png | Bin 0 -> 2547 bytes data/countryflags/VC.png | Bin 0 -> 1495 bytes data/countryflags/VE.png | Bin 0 -> 1342 bytes data/countryflags/VG.png | Bin 0 -> 3211 bytes data/countryflags/VI.png | Bin 0 -> 5088 bytes data/countryflags/VN.png | Bin 0 -> 1278 bytes data/countryflags/VU.png | Bin 0 -> 2410 bytes data/countryflags/WF.png | Bin 0 -> 1263 bytes data/countryflags/WS.png | Bin 0 -> 1216 bytes data/countryflags/XEN.png | Bin 1192 -> 914 bytes data/countryflags/XNI.png | Bin 3701 -> 2212 bytes data/countryflags/XSC.png | Bin 3766 -> 2225 bytes data/countryflags/XWA.png | Bin 6362 -> 4827 bytes data/countryflags/YE.png | Bin 0 -> 699 bytes data/countryflags/ZA.png | Bin 3270 -> 2255 bytes data/countryflags/ZM.png | Bin 0 -> 1272 bytes data/countryflags/ZW.png | Bin 0 -> 2070 bytes data/countryflags/index.txt | 1534 ++++++++++++++++++++++--------------------- 246 files changed, 769 insertions(+), 765 deletions(-) create mode 100644 data/countryflags/AD.png create mode 100644 data/countryflags/AE.png create mode 100644 data/countryflags/AF.png create mode 100644 data/countryflags/AG.png create mode 100644 data/countryflags/AI.png create mode 100644 data/countryflags/AL.png create mode 100644 data/countryflags/AM.png create mode 100644 data/countryflags/AO.png create mode 100644 data/countryflags/AS.png create mode 100644 data/countryflags/AW.png create mode 100644 data/countryflags/AX.png create mode 100644 data/countryflags/AZ.png create mode 100644 data/countryflags/BB.png create mode 100644 data/countryflags/BD.png create mode 100644 data/countryflags/BF.png create mode 100644 data/countryflags/BH.png create mode 100644 data/countryflags/BI.png create mode 100644 data/countryflags/BJ.png create mode 100644 data/countryflags/BL.png create mode 100644 data/countryflags/BM.png create mode 100644 data/countryflags/BN.png create mode 100644 data/countryflags/BO.png create mode 100644 data/countryflags/BS.png create mode 100644 data/countryflags/BT.png create mode 100644 data/countryflags/BW.png create mode 100644 data/countryflags/BZ.png create mode 100644 data/countryflags/CC.png create mode 100644 data/countryflags/CD.png create mode 100644 data/countryflags/CF.png create mode 100644 data/countryflags/CG.png create mode 100644 data/countryflags/CI.png create mode 100644 data/countryflags/CK.png create mode 100644 data/countryflags/CM.png create mode 100644 data/countryflags/CR.png create mode 100644 data/countryflags/CU.png create mode 100644 data/countryflags/CV.png create mode 100644 data/countryflags/CW.png create mode 100644 data/countryflags/CX.png create mode 100644 data/countryflags/CY.png create mode 100644 data/countryflags/DJ.png create mode 100644 data/countryflags/DM.png create mode 100644 data/countryflags/DO.png create mode 100644 data/countryflags/DZ.png create mode 100644 data/countryflags/EC.png create mode 100644 data/countryflags/EH.png create mode 100644 data/countryflags/ER.png create mode 100644 data/countryflags/ET.png create mode 100644 data/countryflags/FJ.png create mode 100644 data/countryflags/FK.png create mode 100644 data/countryflags/FM.png create mode 100644 data/countryflags/FO.png create mode 100644 data/countryflags/GA.png create mode 100644 data/countryflags/GD.png create mode 100644 data/countryflags/GE.png create mode 100644 data/countryflags/GF.png create mode 100644 data/countryflags/GG.png create mode 100644 data/countryflags/GH.png create mode 100644 data/countryflags/GI.png create mode 100644 data/countryflags/GL.png create mode 100644 data/countryflags/GM.png create mode 100644 data/countryflags/GN.png create mode 100644 data/countryflags/GP.png create mode 100644 data/countryflags/GQ.png create mode 100644 data/countryflags/GS.png create mode 100644 data/countryflags/GT.png create mode 100644 data/countryflags/GU.png create mode 100644 data/countryflags/GW.png create mode 100644 data/countryflags/GY.png create mode 100644 data/countryflags/HK.png create mode 100644 data/countryflags/HN.png create mode 100644 data/countryflags/HT.png create mode 100644 data/countryflags/IE.png create mode 100644 data/countryflags/IM.png create mode 100644 data/countryflags/IO.png create mode 100644 data/countryflags/IQ.png create mode 100644 data/countryflags/IS.png create mode 100644 data/countryflags/JE.png create mode 100644 data/countryflags/JM.png create mode 100644 data/countryflags/JO.png create mode 100644 data/countryflags/JP.png create mode 100644 data/countryflags/KE.png create mode 100644 data/countryflags/KG.png create mode 100644 data/countryflags/KH.png create mode 100644 data/countryflags/KI.png create mode 100644 data/countryflags/KM.png create mode 100644 data/countryflags/KN.png create mode 100644 data/countryflags/KP.png create mode 100644 data/countryflags/KR.png create mode 100644 data/countryflags/KW.png create mode 100644 data/countryflags/KY.png create mode 100644 data/countryflags/LA.png create mode 100644 data/countryflags/LB.png create mode 100644 data/countryflags/LC.png create mode 100644 data/countryflags/LI.png create mode 100644 data/countryflags/LK.png create mode 100644 data/countryflags/LR.png create mode 100644 data/countryflags/LS.png create mode 100644 data/countryflags/LY.png create mode 100644 data/countryflags/MA.png create mode 100644 data/countryflags/MC.png create mode 100644 data/countryflags/MD.png create mode 100644 data/countryflags/ME.png create mode 100644 data/countryflags/MF.png create mode 100644 data/countryflags/MG.png create mode 100644 data/countryflags/MH.png create mode 100644 data/countryflags/MK.png create mode 100644 data/countryflags/ML.png create mode 100644 data/countryflags/MM.png create mode 100644 data/countryflags/MN.png create mode 100644 data/countryflags/MO.png create mode 100644 data/countryflags/MP.png create mode 100644 data/countryflags/MQ.png create mode 100644 data/countryflags/MR.png create mode 100644 data/countryflags/MS.png create mode 100644 data/countryflags/MT.png create mode 100644 data/countryflags/MU.png create mode 100644 data/countryflags/MV.png create mode 100644 data/countryflags/MW.png create mode 100644 data/countryflags/MY.png create mode 100644 data/countryflags/MZ.png create mode 100644 data/countryflags/NA.png create mode 100644 data/countryflags/NC.png create mode 100644 data/countryflags/NE.png create mode 100644 data/countryflags/NF.png create mode 100644 data/countryflags/NG.png create mode 100644 data/countryflags/NI.png create mode 100644 data/countryflags/NP.png create mode 100644 data/countryflags/NR.png create mode 100644 data/countryflags/NU.png create mode 100644 data/countryflags/NZ.png create mode 100644 data/countryflags/OM.png create mode 100644 data/countryflags/PA.png create mode 100644 data/countryflags/PE.png create mode 100644 data/countryflags/PF.png create mode 100644 data/countryflags/PG.png create mode 100644 data/countryflags/PM.png create mode 100644 data/countryflags/PN.png create mode 100644 data/countryflags/PR.png create mode 100644 data/countryflags/PW.png create mode 100644 data/countryflags/PY.png create mode 100644 data/countryflags/QA.png create mode 100644 data/countryflags/RE.png create mode 100644 data/countryflags/RW.png create mode 100644 data/countryflags/SB.png create mode 100644 data/countryflags/SC.png create mode 100644 data/countryflags/SD.png create mode 100644 data/countryflags/SG.png create mode 100644 data/countryflags/SH.png create mode 100644 data/countryflags/SI.png create mode 100644 data/countryflags/SL.png create mode 100644 data/countryflags/SM.png create mode 100644 data/countryflags/SN.png create mode 100644 data/countryflags/SO.png create mode 100644 data/countryflags/SR.png create mode 100644 data/countryflags/SS.png create mode 100644 data/countryflags/ST.png create mode 100644 data/countryflags/SX.png create mode 100644 data/countryflags/SY.png create mode 100644 data/countryflags/SZ.png create mode 100644 data/countryflags/TC.png create mode 100644 data/countryflags/TD.png create mode 100644 data/countryflags/TF.png create mode 100644 data/countryflags/TG.png create mode 100644 data/countryflags/TH.png create mode 100644 data/countryflags/TJ.png create mode 100644 data/countryflags/TK.png create mode 100644 data/countryflags/TL.png create mode 100644 data/countryflags/TM.png create mode 100644 data/countryflags/TN.png create mode 100644 data/countryflags/TO.png create mode 100644 data/countryflags/TT.png create mode 100644 data/countryflags/TV.png create mode 100644 data/countryflags/TW.png create mode 100644 data/countryflags/TZ.png create mode 100644 data/countryflags/UG.png create mode 100644 data/countryflags/UY.png create mode 100644 data/countryflags/UZ.png create mode 100644 data/countryflags/VA.png create mode 100644 data/countryflags/VC.png create mode 100644 data/countryflags/VE.png create mode 100644 data/countryflags/VG.png create mode 100644 data/countryflags/VI.png create mode 100644 data/countryflags/VN.png create mode 100644 data/countryflags/VU.png create mode 100644 data/countryflags/WF.png create mode 100644 data/countryflags/WS.png create mode 100644 data/countryflags/YE.png create mode 100644 data/countryflags/ZM.png create mode 100644 data/countryflags/ZW.png diff --git a/data/countryflags/AD.png b/data/countryflags/AD.png new file mode 100644 index 00000000..9977c009 Binary files /dev/null and b/data/countryflags/AD.png differ diff --git a/data/countryflags/AE.png b/data/countryflags/AE.png new file mode 100644 index 00000000..7be66c75 Binary files /dev/null and b/data/countryflags/AE.png differ diff --git a/data/countryflags/AF.png b/data/countryflags/AF.png new file mode 100644 index 00000000..e7f20d1c Binary files /dev/null and b/data/countryflags/AF.png differ diff --git a/data/countryflags/AG.png b/data/countryflags/AG.png new file mode 100644 index 00000000..22fdded8 Binary files /dev/null and b/data/countryflags/AG.png differ diff --git a/data/countryflags/AI.png b/data/countryflags/AI.png new file mode 100644 index 00000000..9056a2b2 Binary files /dev/null and b/data/countryflags/AI.png differ diff --git a/data/countryflags/AL.png b/data/countryflags/AL.png new file mode 100644 index 00000000..acc74619 Binary files /dev/null and b/data/countryflags/AL.png differ diff --git a/data/countryflags/AM.png b/data/countryflags/AM.png new file mode 100644 index 00000000..139c30d9 Binary files /dev/null and b/data/countryflags/AM.png differ diff --git a/data/countryflags/AO.png b/data/countryflags/AO.png new file mode 100644 index 00000000..5b3ca638 Binary files /dev/null and b/data/countryflags/AO.png differ diff --git a/data/countryflags/AR.png b/data/countryflags/AR.png index 0ce5f92b..878458c7 100644 Binary files a/data/countryflags/AR.png and b/data/countryflags/AR.png differ diff --git a/data/countryflags/AS.png b/data/countryflags/AS.png new file mode 100644 index 00000000..b4add724 Binary files /dev/null and b/data/countryflags/AS.png differ diff --git a/data/countryflags/AT.png b/data/countryflags/AT.png index c1fbe9d4..13c6a599 100644 Binary files a/data/countryflags/AT.png and b/data/countryflags/AT.png differ diff --git a/data/countryflags/AU.png b/data/countryflags/AU.png index 361f22e4..6e334645 100644 Binary files a/data/countryflags/AU.png and b/data/countryflags/AU.png differ diff --git a/data/countryflags/AW.png b/data/countryflags/AW.png new file mode 100644 index 00000000..9c89e68c Binary files /dev/null and b/data/countryflags/AW.png differ diff --git a/data/countryflags/AX.png b/data/countryflags/AX.png new file mode 100644 index 00000000..d7fb2236 Binary files /dev/null and b/data/countryflags/AX.png differ diff --git a/data/countryflags/AZ.png b/data/countryflags/AZ.png new file mode 100644 index 00000000..49bcb835 Binary files /dev/null and b/data/countryflags/AZ.png differ diff --git a/data/countryflags/BA.png b/data/countryflags/BA.png index 3a77a439..21397f63 100644 Binary files a/data/countryflags/BA.png and b/data/countryflags/BA.png differ diff --git a/data/countryflags/BB.png b/data/countryflags/BB.png new file mode 100644 index 00000000..051b3032 Binary files /dev/null and b/data/countryflags/BB.png differ diff --git a/data/countryflags/BD.png b/data/countryflags/BD.png new file mode 100644 index 00000000..1488cf27 Binary files /dev/null and b/data/countryflags/BD.png differ diff --git a/data/countryflags/BE.png b/data/countryflags/BE.png index 409e8552..b6135ec6 100644 Binary files a/data/countryflags/BE.png and b/data/countryflags/BE.png differ diff --git a/data/countryflags/BF.png b/data/countryflags/BF.png new file mode 100644 index 00000000..fd1fa109 Binary files /dev/null and b/data/countryflags/BF.png differ diff --git a/data/countryflags/BG.png b/data/countryflags/BG.png index 7f9a6590..f323e5d0 100644 Binary files a/data/countryflags/BG.png and b/data/countryflags/BG.png differ diff --git a/data/countryflags/BH.png b/data/countryflags/BH.png new file mode 100644 index 00000000..59c8a487 Binary files /dev/null and b/data/countryflags/BH.png differ diff --git a/data/countryflags/BI.png b/data/countryflags/BI.png new file mode 100644 index 00000000..08f0ec47 Binary files /dev/null and b/data/countryflags/BI.png differ diff --git a/data/countryflags/BJ.png b/data/countryflags/BJ.png new file mode 100644 index 00000000..74725ce9 Binary files /dev/null and b/data/countryflags/BJ.png differ diff --git a/data/countryflags/BL.png b/data/countryflags/BL.png new file mode 100644 index 00000000..692401bd Binary files /dev/null and b/data/countryflags/BL.png differ diff --git a/data/countryflags/BM.png b/data/countryflags/BM.png new file mode 100644 index 00000000..9d7cd871 Binary files /dev/null and b/data/countryflags/BM.png differ diff --git a/data/countryflags/BN.png b/data/countryflags/BN.png new file mode 100644 index 00000000..38dd8cc9 Binary files /dev/null and b/data/countryflags/BN.png differ diff --git a/data/countryflags/BO.png b/data/countryflags/BO.png new file mode 100644 index 00000000..028e1fe3 Binary files /dev/null and b/data/countryflags/BO.png differ diff --git a/data/countryflags/BR.png b/data/countryflags/BR.png index aada91d5..5c2ea746 100644 Binary files a/data/countryflags/BR.png and b/data/countryflags/BR.png differ diff --git a/data/countryflags/BS.png b/data/countryflags/BS.png new file mode 100644 index 00000000..aae921df Binary files /dev/null and b/data/countryflags/BS.png differ diff --git a/data/countryflags/BT.png b/data/countryflags/BT.png new file mode 100644 index 00000000..130b9045 Binary files /dev/null and b/data/countryflags/BT.png differ diff --git a/data/countryflags/BW.png b/data/countryflags/BW.png new file mode 100644 index 00000000..d7782c6e Binary files /dev/null and b/data/countryflags/BW.png differ diff --git a/data/countryflags/BY.png b/data/countryflags/BY.png index 6052eea4..c05a3664 100644 Binary files a/data/countryflags/BY.png and b/data/countryflags/BY.png differ diff --git a/data/countryflags/BZ.png b/data/countryflags/BZ.png new file mode 100644 index 00000000..93f832e5 Binary files /dev/null and b/data/countryflags/BZ.png differ diff --git a/data/countryflags/CA.png b/data/countryflags/CA.png index 9898ba57..9d9f4a1e 100644 Binary files a/data/countryflags/CA.png and b/data/countryflags/CA.png differ diff --git a/data/countryflags/CC.png b/data/countryflags/CC.png new file mode 100644 index 00000000..ef1b1dd2 Binary files /dev/null and b/data/countryflags/CC.png differ diff --git a/data/countryflags/CD.png b/data/countryflags/CD.png new file mode 100644 index 00000000..3c5f2f95 Binary files /dev/null and b/data/countryflags/CD.png differ diff --git a/data/countryflags/CF.png b/data/countryflags/CF.png new file mode 100644 index 00000000..e42de4dc Binary files /dev/null and b/data/countryflags/CF.png differ diff --git a/data/countryflags/CG.png b/data/countryflags/CG.png new file mode 100644 index 00000000..99a97ea1 Binary files /dev/null and b/data/countryflags/CG.png differ diff --git a/data/countryflags/CH.png b/data/countryflags/CH.png index fa8d6482..27881d0c 100644 Binary files a/data/countryflags/CH.png and b/data/countryflags/CH.png differ diff --git a/data/countryflags/CI.png b/data/countryflags/CI.png new file mode 100644 index 00000000..fa80f60b Binary files /dev/null and b/data/countryflags/CI.png differ diff --git a/data/countryflags/CK.png b/data/countryflags/CK.png new file mode 100644 index 00000000..c7a8d325 Binary files /dev/null and b/data/countryflags/CK.png differ diff --git a/data/countryflags/CL.png b/data/countryflags/CL.png index 571851c7..327b27f6 100644 Binary files a/data/countryflags/CL.png and b/data/countryflags/CL.png differ diff --git a/data/countryflags/CM.png b/data/countryflags/CM.png new file mode 100644 index 00000000..9e983e2d Binary files /dev/null and b/data/countryflags/CM.png differ diff --git a/data/countryflags/CN.png b/data/countryflags/CN.png index 3251bd9a..1996131e 100644 Binary files a/data/countryflags/CN.png and b/data/countryflags/CN.png differ diff --git a/data/countryflags/CO.png b/data/countryflags/CO.png index 5fdda4a5..61f8fa55 100644 Binary files a/data/countryflags/CO.png and b/data/countryflags/CO.png differ diff --git a/data/countryflags/CR.png b/data/countryflags/CR.png new file mode 100644 index 00000000..f6a02efd Binary files /dev/null and b/data/countryflags/CR.png differ diff --git a/data/countryflags/CU.png b/data/countryflags/CU.png new file mode 100644 index 00000000..0dbee8c2 Binary files /dev/null and b/data/countryflags/CU.png differ diff --git a/data/countryflags/CV.png b/data/countryflags/CV.png new file mode 100644 index 00000000..95afe4b5 Binary files /dev/null and b/data/countryflags/CV.png differ diff --git a/data/countryflags/CW.png b/data/countryflags/CW.png new file mode 100644 index 00000000..079ec877 Binary files /dev/null and b/data/countryflags/CW.png differ diff --git a/data/countryflags/CX.png b/data/countryflags/CX.png new file mode 100644 index 00000000..12051034 Binary files /dev/null and b/data/countryflags/CX.png differ diff --git a/data/countryflags/CY.png b/data/countryflags/CY.png new file mode 100644 index 00000000..dd34d6c4 Binary files /dev/null and b/data/countryflags/CY.png differ diff --git a/data/countryflags/CZ.png b/data/countryflags/CZ.png index cb750877..b4df10db 100644 Binary files a/data/countryflags/CZ.png and b/data/countryflags/CZ.png differ diff --git a/data/countryflags/DE.png b/data/countryflags/DE.png index 699a43d8..dde74c9e 100644 Binary files a/data/countryflags/DE.png and b/data/countryflags/DE.png differ diff --git a/data/countryflags/DJ.png b/data/countryflags/DJ.png new file mode 100644 index 00000000..62a8c250 Binary files /dev/null and b/data/countryflags/DJ.png differ diff --git a/data/countryflags/DK.png b/data/countryflags/DK.png index df04cf93..4125f604 100644 Binary files a/data/countryflags/DK.png and b/data/countryflags/DK.png differ diff --git a/data/countryflags/DM.png b/data/countryflags/DM.png new file mode 100644 index 00000000..3ea6cf59 Binary files /dev/null and b/data/countryflags/DM.png differ diff --git a/data/countryflags/DO.png b/data/countryflags/DO.png new file mode 100644 index 00000000..f70848f5 Binary files /dev/null and b/data/countryflags/DO.png differ diff --git a/data/countryflags/DZ.png b/data/countryflags/DZ.png new file mode 100644 index 00000000..31df99f3 Binary files /dev/null and b/data/countryflags/DZ.png differ diff --git a/data/countryflags/EC.png b/data/countryflags/EC.png new file mode 100644 index 00000000..80dfbaa2 Binary files /dev/null and b/data/countryflags/EC.png differ diff --git a/data/countryflags/EE.png b/data/countryflags/EE.png index 45ef482f..6dc9933a 100644 Binary files a/data/countryflags/EE.png and b/data/countryflags/EE.png differ diff --git a/data/countryflags/EG.png b/data/countryflags/EG.png index 3cd437d3..b0c3bf52 100644 Binary files a/data/countryflags/EG.png and b/data/countryflags/EG.png differ diff --git a/data/countryflags/EH.png b/data/countryflags/EH.png new file mode 100644 index 00000000..9af42a3b Binary files /dev/null and b/data/countryflags/EH.png differ diff --git a/data/countryflags/ER.png b/data/countryflags/ER.png new file mode 100644 index 00000000..88dd0706 Binary files /dev/null and b/data/countryflags/ER.png differ diff --git a/data/countryflags/ES.png b/data/countryflags/ES.png index b507a328..412b2107 100644 Binary files a/data/countryflags/ES.png and b/data/countryflags/ES.png differ diff --git a/data/countryflags/ET.png b/data/countryflags/ET.png new file mode 100644 index 00000000..9588ce9a Binary files /dev/null and b/data/countryflags/ET.png differ diff --git a/data/countryflags/FI.png b/data/countryflags/FI.png index 96b39593..0373e03e 100644 Binary files a/data/countryflags/FI.png and b/data/countryflags/FI.png differ diff --git a/data/countryflags/FJ.png b/data/countryflags/FJ.png new file mode 100644 index 00000000..9d2af629 Binary files /dev/null and b/data/countryflags/FJ.png differ diff --git a/data/countryflags/FK.png b/data/countryflags/FK.png new file mode 100644 index 00000000..a3f2ad34 Binary files /dev/null and b/data/countryflags/FK.png differ diff --git a/data/countryflags/FM.png b/data/countryflags/FM.png new file mode 100644 index 00000000..c0cd4cf1 Binary files /dev/null and b/data/countryflags/FM.png differ diff --git a/data/countryflags/FO.png b/data/countryflags/FO.png new file mode 100644 index 00000000..e46c2eb3 Binary files /dev/null and b/data/countryflags/FO.png differ diff --git a/data/countryflags/FR.png b/data/countryflags/FR.png index f85cfa49..eb4ec8ab 100644 Binary files a/data/countryflags/FR.png and b/data/countryflags/FR.png differ diff --git a/data/countryflags/GA.png b/data/countryflags/GA.png new file mode 100644 index 00000000..446d380d Binary files /dev/null and b/data/countryflags/GA.png differ diff --git a/data/countryflags/GB.png b/data/countryflags/GB.png index 240adcc7..4aa46067 100644 Binary files a/data/countryflags/GB.png and b/data/countryflags/GB.png differ diff --git a/data/countryflags/GD.png b/data/countryflags/GD.png new file mode 100644 index 00000000..538e8e09 Binary files /dev/null and b/data/countryflags/GD.png differ diff --git a/data/countryflags/GE.png b/data/countryflags/GE.png new file mode 100644 index 00000000..67953847 Binary files /dev/null and b/data/countryflags/GE.png differ diff --git a/data/countryflags/GF.png b/data/countryflags/GF.png new file mode 100644 index 00000000..2b804f54 Binary files /dev/null and b/data/countryflags/GF.png differ diff --git a/data/countryflags/GG.png b/data/countryflags/GG.png new file mode 100644 index 00000000..472924fb Binary files /dev/null and b/data/countryflags/GG.png differ diff --git a/data/countryflags/GH.png b/data/countryflags/GH.png new file mode 100644 index 00000000..2809250f Binary files /dev/null and b/data/countryflags/GH.png differ diff --git a/data/countryflags/GI.png b/data/countryflags/GI.png new file mode 100644 index 00000000..9c88bfd4 Binary files /dev/null and b/data/countryflags/GI.png differ diff --git a/data/countryflags/GL.png b/data/countryflags/GL.png new file mode 100644 index 00000000..6191d23c Binary files /dev/null and b/data/countryflags/GL.png differ diff --git a/data/countryflags/GM.png b/data/countryflags/GM.png new file mode 100644 index 00000000..ce94adfd Binary files /dev/null and b/data/countryflags/GM.png differ diff --git a/data/countryflags/GN.png b/data/countryflags/GN.png new file mode 100644 index 00000000..3f698559 Binary files /dev/null and b/data/countryflags/GN.png differ diff --git a/data/countryflags/GP.png b/data/countryflags/GP.png new file mode 100644 index 00000000..bff1c31f Binary files /dev/null and b/data/countryflags/GP.png differ diff --git a/data/countryflags/GQ.png b/data/countryflags/GQ.png new file mode 100644 index 00000000..3a7dc2c5 Binary files /dev/null and b/data/countryflags/GQ.png differ diff --git a/data/countryflags/GR.png b/data/countryflags/GR.png index 18eaeb28..a9dcd902 100644 Binary files a/data/countryflags/GR.png and b/data/countryflags/GR.png differ diff --git a/data/countryflags/GS.png b/data/countryflags/GS.png new file mode 100644 index 00000000..bdeda46f Binary files /dev/null and b/data/countryflags/GS.png differ diff --git a/data/countryflags/GT.png b/data/countryflags/GT.png new file mode 100644 index 00000000..9ed9c11b Binary files /dev/null and b/data/countryflags/GT.png differ diff --git a/data/countryflags/GU.png b/data/countryflags/GU.png new file mode 100644 index 00000000..1a0affcd Binary files /dev/null and b/data/countryflags/GU.png differ diff --git a/data/countryflags/GW.png b/data/countryflags/GW.png new file mode 100644 index 00000000..b22b8d0e Binary files /dev/null and b/data/countryflags/GW.png differ diff --git a/data/countryflags/GY.png b/data/countryflags/GY.png new file mode 100644 index 00000000..35fd8c8f Binary files /dev/null and b/data/countryflags/GY.png differ diff --git a/data/countryflags/HK.png b/data/countryflags/HK.png new file mode 100644 index 00000000..6e4b18ce Binary files /dev/null and b/data/countryflags/HK.png differ diff --git a/data/countryflags/HN.png b/data/countryflags/HN.png new file mode 100644 index 00000000..09504718 Binary files /dev/null and b/data/countryflags/HN.png differ diff --git a/data/countryflags/HR.png b/data/countryflags/HR.png index 6097adc7..c844d4f4 100644 Binary files a/data/countryflags/HR.png and b/data/countryflags/HR.png differ diff --git a/data/countryflags/HT.png b/data/countryflags/HT.png new file mode 100644 index 00000000..3ab3e79f Binary files /dev/null and b/data/countryflags/HT.png differ diff --git a/data/countryflags/HU.png b/data/countryflags/HU.png index 20c21f0e..8106da42 100644 Binary files a/data/countryflags/HU.png and b/data/countryflags/HU.png differ diff --git a/data/countryflags/ID.png b/data/countryflags/ID.png index 510bac08..49b52e3c 100644 Binary files a/data/countryflags/ID.png and b/data/countryflags/ID.png differ diff --git a/data/countryflags/IE.png b/data/countryflags/IE.png new file mode 100644 index 00000000..df9be88f Binary files /dev/null and b/data/countryflags/IE.png differ diff --git a/data/countryflags/IL.png b/data/countryflags/IL.png index 3852a8f9..ce4acc73 100644 Binary files a/data/countryflags/IL.png and b/data/countryflags/IL.png differ diff --git a/data/countryflags/IM.png b/data/countryflags/IM.png new file mode 100644 index 00000000..efd55fe4 Binary files /dev/null and b/data/countryflags/IM.png differ diff --git a/data/countryflags/IN.png b/data/countryflags/IN.png index 91d34696..c4f8dbf0 100644 Binary files a/data/countryflags/IN.png and b/data/countryflags/IN.png differ diff --git a/data/countryflags/IO.png b/data/countryflags/IO.png new file mode 100644 index 00000000..e983a3f2 Binary files /dev/null and b/data/countryflags/IO.png differ diff --git a/data/countryflags/IQ.png b/data/countryflags/IQ.png new file mode 100644 index 00000000..81e7a8b4 Binary files /dev/null and b/data/countryflags/IQ.png differ diff --git a/data/countryflags/IR.png b/data/countryflags/IR.png index 141a0e56..dcb71c3a 100644 Binary files a/data/countryflags/IR.png and b/data/countryflags/IR.png differ diff --git a/data/countryflags/IS.png b/data/countryflags/IS.png new file mode 100644 index 00000000..4307fdfd Binary files /dev/null and b/data/countryflags/IS.png differ diff --git a/data/countryflags/IT.png b/data/countryflags/IT.png index 4d4a1b3e..7372d812 100644 Binary files a/data/countryflags/IT.png and b/data/countryflags/IT.png differ diff --git a/data/countryflags/JE.png b/data/countryflags/JE.png new file mode 100644 index 00000000..a6b50b0c Binary files /dev/null and b/data/countryflags/JE.png differ diff --git a/data/countryflags/JM.png b/data/countryflags/JM.png new file mode 100644 index 00000000..94cf3abf Binary files /dev/null and b/data/countryflags/JM.png differ diff --git a/data/countryflags/JO.png b/data/countryflags/JO.png new file mode 100644 index 00000000..0bb6cb65 Binary files /dev/null and b/data/countryflags/JO.png differ diff --git a/data/countryflags/JP.png b/data/countryflags/JP.png new file mode 100644 index 00000000..ddfdfb5c Binary files /dev/null and b/data/countryflags/JP.png differ diff --git a/data/countryflags/KE.png b/data/countryflags/KE.png new file mode 100644 index 00000000..e44c27d6 Binary files /dev/null and b/data/countryflags/KE.png differ diff --git a/data/countryflags/KG.png b/data/countryflags/KG.png new file mode 100644 index 00000000..1c57fbbc Binary files /dev/null and b/data/countryflags/KG.png differ diff --git a/data/countryflags/KH.png b/data/countryflags/KH.png new file mode 100644 index 00000000..102bc024 Binary files /dev/null and b/data/countryflags/KH.png differ diff --git a/data/countryflags/KI.png b/data/countryflags/KI.png new file mode 100644 index 00000000..7f62de60 Binary files /dev/null and b/data/countryflags/KI.png differ diff --git a/data/countryflags/KM.png b/data/countryflags/KM.png new file mode 100644 index 00000000..f6a77ecc Binary files /dev/null and b/data/countryflags/KM.png differ diff --git a/data/countryflags/KN.png b/data/countryflags/KN.png new file mode 100644 index 00000000..06f6a9f9 Binary files /dev/null and b/data/countryflags/KN.png differ diff --git a/data/countryflags/KP.png b/data/countryflags/KP.png new file mode 100644 index 00000000..48093061 Binary files /dev/null and b/data/countryflags/KP.png differ diff --git a/data/countryflags/KR.png b/data/countryflags/KR.png new file mode 100644 index 00000000..32a83733 Binary files /dev/null and b/data/countryflags/KR.png differ diff --git a/data/countryflags/KW.png b/data/countryflags/KW.png new file mode 100644 index 00000000..557e38b1 Binary files /dev/null and b/data/countryflags/KW.png differ diff --git a/data/countryflags/KY.png b/data/countryflags/KY.png new file mode 100644 index 00000000..020dbeef Binary files /dev/null and b/data/countryflags/KY.png differ diff --git a/data/countryflags/KZ.png b/data/countryflags/KZ.png index e3db4f93..d0b6eede 100644 Binary files a/data/countryflags/KZ.png and b/data/countryflags/KZ.png differ diff --git a/data/countryflags/LA.png b/data/countryflags/LA.png new file mode 100644 index 00000000..bfe966f6 Binary files /dev/null and b/data/countryflags/LA.png differ diff --git a/data/countryflags/LB.png b/data/countryflags/LB.png new file mode 100644 index 00000000..3c8ef00c Binary files /dev/null and b/data/countryflags/LB.png differ diff --git a/data/countryflags/LC.png b/data/countryflags/LC.png new file mode 100644 index 00000000..19b5f78a Binary files /dev/null and b/data/countryflags/LC.png differ diff --git a/data/countryflags/LI.png b/data/countryflags/LI.png new file mode 100644 index 00000000..06daeeb8 Binary files /dev/null and b/data/countryflags/LI.png differ diff --git a/data/countryflags/LK.png b/data/countryflags/LK.png new file mode 100644 index 00000000..f7710ae9 Binary files /dev/null and b/data/countryflags/LK.png differ diff --git a/data/countryflags/LR.png b/data/countryflags/LR.png new file mode 100644 index 00000000..6d361dff Binary files /dev/null and b/data/countryflags/LR.png differ diff --git a/data/countryflags/LS.png b/data/countryflags/LS.png new file mode 100644 index 00000000..02a844fe Binary files /dev/null and b/data/countryflags/LS.png differ diff --git a/data/countryflags/LT.png b/data/countryflags/LT.png index dd1d3d13..c37e857f 100644 Binary files a/data/countryflags/LT.png and b/data/countryflags/LT.png differ diff --git a/data/countryflags/LU.png b/data/countryflags/LU.png index 01377c56..ed89b616 100644 Binary files a/data/countryflags/LU.png and b/data/countryflags/LU.png differ diff --git a/data/countryflags/LV.png b/data/countryflags/LV.png index 8915e25d..f5f51afc 100644 Binary files a/data/countryflags/LV.png and b/data/countryflags/LV.png differ diff --git a/data/countryflags/LY.png b/data/countryflags/LY.png new file mode 100644 index 00000000..1dda0198 Binary files /dev/null and b/data/countryflags/LY.png differ diff --git a/data/countryflags/MA.png b/data/countryflags/MA.png new file mode 100644 index 00000000..0ae330bb Binary files /dev/null and b/data/countryflags/MA.png differ diff --git a/data/countryflags/MC.png b/data/countryflags/MC.png new file mode 100644 index 00000000..5a73c3c1 Binary files /dev/null and b/data/countryflags/MC.png differ diff --git a/data/countryflags/MD.png b/data/countryflags/MD.png new file mode 100644 index 00000000..d713b079 Binary files /dev/null and b/data/countryflags/MD.png differ diff --git a/data/countryflags/ME.png b/data/countryflags/ME.png new file mode 100644 index 00000000..f6348bda Binary files /dev/null and b/data/countryflags/ME.png differ diff --git a/data/countryflags/MF.png b/data/countryflags/MF.png new file mode 100644 index 00000000..0fa201c9 Binary files /dev/null and b/data/countryflags/MF.png differ diff --git a/data/countryflags/MG.png b/data/countryflags/MG.png new file mode 100644 index 00000000..52030837 Binary files /dev/null and b/data/countryflags/MG.png differ diff --git a/data/countryflags/MH.png b/data/countryflags/MH.png new file mode 100644 index 00000000..40d7bd3d Binary files /dev/null and b/data/countryflags/MH.png differ diff --git a/data/countryflags/MK.png b/data/countryflags/MK.png new file mode 100644 index 00000000..3743d81a Binary files /dev/null and b/data/countryflags/MK.png differ diff --git a/data/countryflags/ML.png b/data/countryflags/ML.png new file mode 100644 index 00000000..d548a1e2 Binary files /dev/null and b/data/countryflags/ML.png differ diff --git a/data/countryflags/MM.png b/data/countryflags/MM.png new file mode 100644 index 00000000..58c098b8 Binary files /dev/null and b/data/countryflags/MM.png differ diff --git a/data/countryflags/MN.png b/data/countryflags/MN.png new file mode 100644 index 00000000..1d9f5159 Binary files /dev/null and b/data/countryflags/MN.png differ diff --git a/data/countryflags/MO.png b/data/countryflags/MO.png new file mode 100644 index 00000000..6adda298 Binary files /dev/null and b/data/countryflags/MO.png differ diff --git a/data/countryflags/MP.png b/data/countryflags/MP.png new file mode 100644 index 00000000..6b308645 Binary files /dev/null and b/data/countryflags/MP.png differ diff --git a/data/countryflags/MQ.png b/data/countryflags/MQ.png new file mode 100644 index 00000000..2f3c556a Binary files /dev/null and b/data/countryflags/MQ.png differ diff --git a/data/countryflags/MR.png b/data/countryflags/MR.png new file mode 100644 index 00000000..8c6462ba Binary files /dev/null and b/data/countryflags/MR.png differ diff --git a/data/countryflags/MS.png b/data/countryflags/MS.png new file mode 100644 index 00000000..27312023 Binary files /dev/null and b/data/countryflags/MS.png differ diff --git a/data/countryflags/MT.png b/data/countryflags/MT.png new file mode 100644 index 00000000..043ea73e Binary files /dev/null and b/data/countryflags/MT.png differ diff --git a/data/countryflags/MU.png b/data/countryflags/MU.png new file mode 100644 index 00000000..02a5f3af Binary files /dev/null and b/data/countryflags/MU.png differ diff --git a/data/countryflags/MV.png b/data/countryflags/MV.png new file mode 100644 index 00000000..6a3fd961 Binary files /dev/null and b/data/countryflags/MV.png differ diff --git a/data/countryflags/MW.png b/data/countryflags/MW.png new file mode 100644 index 00000000..5d26e5f7 Binary files /dev/null and b/data/countryflags/MW.png differ diff --git a/data/countryflags/MX.png b/data/countryflags/MX.png index 9505d623..19c7ddea 100644 Binary files a/data/countryflags/MX.png and b/data/countryflags/MX.png differ diff --git a/data/countryflags/MY.png b/data/countryflags/MY.png new file mode 100644 index 00000000..885ba638 Binary files /dev/null and b/data/countryflags/MY.png differ diff --git a/data/countryflags/MZ.png b/data/countryflags/MZ.png new file mode 100644 index 00000000..caa5cb4d Binary files /dev/null and b/data/countryflags/MZ.png differ diff --git a/data/countryflags/NA.png b/data/countryflags/NA.png new file mode 100644 index 00000000..f6936933 Binary files /dev/null and b/data/countryflags/NA.png differ diff --git a/data/countryflags/NC.png b/data/countryflags/NC.png new file mode 100644 index 00000000..5f3b0892 Binary files /dev/null and b/data/countryflags/NC.png differ diff --git a/data/countryflags/NE.png b/data/countryflags/NE.png new file mode 100644 index 00000000..7d73f48e Binary files /dev/null and b/data/countryflags/NE.png differ diff --git a/data/countryflags/NF.png b/data/countryflags/NF.png new file mode 100644 index 00000000..5f5401d7 Binary files /dev/null and b/data/countryflags/NF.png differ diff --git a/data/countryflags/NG.png b/data/countryflags/NG.png new file mode 100644 index 00000000..e9030716 Binary files /dev/null and b/data/countryflags/NG.png differ diff --git a/data/countryflags/NI.png b/data/countryflags/NI.png new file mode 100644 index 00000000..19df0e95 Binary files /dev/null and b/data/countryflags/NI.png differ diff --git a/data/countryflags/NL.png b/data/countryflags/NL.png index 5882be49..ba54b03c 100644 Binary files a/data/countryflags/NL.png and b/data/countryflags/NL.png differ diff --git a/data/countryflags/NO.png b/data/countryflags/NO.png index 2e9bbec9..6f085323 100644 Binary files a/data/countryflags/NO.png and b/data/countryflags/NO.png differ diff --git a/data/countryflags/NP.png b/data/countryflags/NP.png new file mode 100644 index 00000000..53c7510a Binary files /dev/null and b/data/countryflags/NP.png differ diff --git a/data/countryflags/NR.png b/data/countryflags/NR.png new file mode 100644 index 00000000..562be4fc Binary files /dev/null and b/data/countryflags/NR.png differ diff --git a/data/countryflags/NU.png b/data/countryflags/NU.png new file mode 100644 index 00000000..1928bab6 Binary files /dev/null and b/data/countryflags/NU.png differ diff --git a/data/countryflags/NZ.png b/data/countryflags/NZ.png new file mode 100644 index 00000000..4e210491 Binary files /dev/null and b/data/countryflags/NZ.png differ diff --git a/data/countryflags/OM.png b/data/countryflags/OM.png new file mode 100644 index 00000000..8b6aba47 Binary files /dev/null and b/data/countryflags/OM.png differ diff --git a/data/countryflags/PA.png b/data/countryflags/PA.png new file mode 100644 index 00000000..ef051c61 Binary files /dev/null and b/data/countryflags/PA.png differ diff --git a/data/countryflags/PE.png b/data/countryflags/PE.png new file mode 100644 index 00000000..f6188650 Binary files /dev/null and b/data/countryflags/PE.png differ diff --git a/data/countryflags/PF.png b/data/countryflags/PF.png new file mode 100644 index 00000000..bf04554d Binary files /dev/null and b/data/countryflags/PF.png differ diff --git a/data/countryflags/PG.png b/data/countryflags/PG.png new file mode 100644 index 00000000..04b36a38 Binary files /dev/null and b/data/countryflags/PG.png differ diff --git a/data/countryflags/PH.png b/data/countryflags/PH.png index ebcec1f2..edb506c0 100644 Binary files a/data/countryflags/PH.png and b/data/countryflags/PH.png differ diff --git a/data/countryflags/PK.png b/data/countryflags/PK.png index 6e4e4950..6030b86b 100644 Binary files a/data/countryflags/PK.png and b/data/countryflags/PK.png differ diff --git a/data/countryflags/PL.png b/data/countryflags/PL.png index 6e6a5c95..03b9e71f 100644 Binary files a/data/countryflags/PL.png and b/data/countryflags/PL.png differ diff --git a/data/countryflags/PM.png b/data/countryflags/PM.png new file mode 100644 index 00000000..dd0dce93 Binary files /dev/null and b/data/countryflags/PM.png differ diff --git a/data/countryflags/PN.png b/data/countryflags/PN.png new file mode 100644 index 00000000..a14628bb Binary files /dev/null and b/data/countryflags/PN.png differ diff --git a/data/countryflags/PR.png b/data/countryflags/PR.png new file mode 100644 index 00000000..6a3f6014 Binary files /dev/null and b/data/countryflags/PR.png differ diff --git a/data/countryflags/PT.png b/data/countryflags/PT.png index b3be0973..ca90e6e9 100644 Binary files a/data/countryflags/PT.png and b/data/countryflags/PT.png differ diff --git a/data/countryflags/PW.png b/data/countryflags/PW.png new file mode 100644 index 00000000..49ee4480 Binary files /dev/null and b/data/countryflags/PW.png differ diff --git a/data/countryflags/PY.png b/data/countryflags/PY.png new file mode 100644 index 00000000..948f7151 Binary files /dev/null and b/data/countryflags/PY.png differ diff --git a/data/countryflags/QA.png b/data/countryflags/QA.png new file mode 100644 index 00000000..cae22d2b Binary files /dev/null and b/data/countryflags/QA.png differ diff --git a/data/countryflags/RE.png b/data/countryflags/RE.png new file mode 100644 index 00000000..5efe1da4 Binary files /dev/null and b/data/countryflags/RE.png differ diff --git a/data/countryflags/RO.png b/data/countryflags/RO.png index 4eae6d22..6ea76a88 100644 Binary files a/data/countryflags/RO.png and b/data/countryflags/RO.png differ diff --git a/data/countryflags/RS.png b/data/countryflags/RS.png index 7cc06394..24e067b4 100644 Binary files a/data/countryflags/RS.png and b/data/countryflags/RS.png differ diff --git a/data/countryflags/RU.png b/data/countryflags/RU.png index ed293810..74a8528f 100644 Binary files a/data/countryflags/RU.png and b/data/countryflags/RU.png differ diff --git a/data/countryflags/RW.png b/data/countryflags/RW.png new file mode 100644 index 00000000..57d3ac5f Binary files /dev/null and b/data/countryflags/RW.png differ diff --git a/data/countryflags/SA.png b/data/countryflags/SA.png index fbfb6cf5..93598245 100644 Binary files a/data/countryflags/SA.png and b/data/countryflags/SA.png differ diff --git a/data/countryflags/SB.png b/data/countryflags/SB.png new file mode 100644 index 00000000..7c4c468d Binary files /dev/null and b/data/countryflags/SB.png differ diff --git a/data/countryflags/SC.png b/data/countryflags/SC.png new file mode 100644 index 00000000..5237f2e8 Binary files /dev/null and b/data/countryflags/SC.png differ diff --git a/data/countryflags/SD.png b/data/countryflags/SD.png new file mode 100644 index 00000000..6adab5ad Binary files /dev/null and b/data/countryflags/SD.png differ diff --git a/data/countryflags/SE.png b/data/countryflags/SE.png index c5c9cda9..47dcef3f 100644 Binary files a/data/countryflags/SE.png and b/data/countryflags/SE.png differ diff --git a/data/countryflags/SG.png b/data/countryflags/SG.png new file mode 100644 index 00000000..c54a7608 Binary files /dev/null and b/data/countryflags/SG.png differ diff --git a/data/countryflags/SH.png b/data/countryflags/SH.png new file mode 100644 index 00000000..a9b6fc9f Binary files /dev/null and b/data/countryflags/SH.png differ diff --git a/data/countryflags/SI.png b/data/countryflags/SI.png new file mode 100644 index 00000000..1e553fd5 Binary files /dev/null and b/data/countryflags/SI.png differ diff --git a/data/countryflags/SK.png b/data/countryflags/SK.png index 5bd535a1..9c927e8f 100644 Binary files a/data/countryflags/SK.png and b/data/countryflags/SK.png differ diff --git a/data/countryflags/SL.png b/data/countryflags/SL.png new file mode 100644 index 00000000..5d1d42fe Binary files /dev/null and b/data/countryflags/SL.png differ diff --git a/data/countryflags/SM.png b/data/countryflags/SM.png new file mode 100644 index 00000000..96726305 Binary files /dev/null and b/data/countryflags/SM.png differ diff --git a/data/countryflags/SN.png b/data/countryflags/SN.png new file mode 100644 index 00000000..42a57326 Binary files /dev/null and b/data/countryflags/SN.png differ diff --git a/data/countryflags/SO.png b/data/countryflags/SO.png new file mode 100644 index 00000000..93815d27 Binary files /dev/null and b/data/countryflags/SO.png differ diff --git a/data/countryflags/SR.png b/data/countryflags/SR.png new file mode 100644 index 00000000..06fe40f3 Binary files /dev/null and b/data/countryflags/SR.png differ diff --git a/data/countryflags/SS.png b/data/countryflags/SS.png new file mode 100644 index 00000000..203c51da Binary files /dev/null and b/data/countryflags/SS.png differ diff --git a/data/countryflags/ST.png b/data/countryflags/ST.png new file mode 100644 index 00000000..748030a0 Binary files /dev/null and b/data/countryflags/ST.png differ diff --git a/data/countryflags/SV.png b/data/countryflags/SV.png index d313b0c1..d03b8be4 100644 Binary files a/data/countryflags/SV.png and b/data/countryflags/SV.png differ diff --git a/data/countryflags/SX.png b/data/countryflags/SX.png new file mode 100644 index 00000000..61606935 Binary files /dev/null and b/data/countryflags/SX.png differ diff --git a/data/countryflags/SY.png b/data/countryflags/SY.png new file mode 100644 index 00000000..04342871 Binary files /dev/null and b/data/countryflags/SY.png differ diff --git a/data/countryflags/SZ.png b/data/countryflags/SZ.png new file mode 100644 index 00000000..bea99b2c Binary files /dev/null and b/data/countryflags/SZ.png differ diff --git a/data/countryflags/TC.png b/data/countryflags/TC.png new file mode 100644 index 00000000..0abdc845 Binary files /dev/null and b/data/countryflags/TC.png differ diff --git a/data/countryflags/TD.png b/data/countryflags/TD.png new file mode 100644 index 00000000..4ffcc670 Binary files /dev/null and b/data/countryflags/TD.png differ diff --git a/data/countryflags/TF.png b/data/countryflags/TF.png new file mode 100644 index 00000000..d3095b29 Binary files /dev/null and b/data/countryflags/TF.png differ diff --git a/data/countryflags/TG.png b/data/countryflags/TG.png new file mode 100644 index 00000000..797f48cd Binary files /dev/null and b/data/countryflags/TG.png differ diff --git a/data/countryflags/TH.png b/data/countryflags/TH.png new file mode 100644 index 00000000..97e22df3 Binary files /dev/null and b/data/countryflags/TH.png differ diff --git a/data/countryflags/TJ.png b/data/countryflags/TJ.png new file mode 100644 index 00000000..54d9830f Binary files /dev/null and b/data/countryflags/TJ.png differ diff --git a/data/countryflags/TK.png b/data/countryflags/TK.png new file mode 100644 index 00000000..623f69e0 Binary files /dev/null and b/data/countryflags/TK.png differ diff --git a/data/countryflags/TL.png b/data/countryflags/TL.png new file mode 100644 index 00000000..5c6f1ff7 Binary files /dev/null and b/data/countryflags/TL.png differ diff --git a/data/countryflags/TM.png b/data/countryflags/TM.png new file mode 100644 index 00000000..40767589 Binary files /dev/null and b/data/countryflags/TM.png differ diff --git a/data/countryflags/TN.png b/data/countryflags/TN.png new file mode 100644 index 00000000..10f9f696 Binary files /dev/null and b/data/countryflags/TN.png differ diff --git a/data/countryflags/TO.png b/data/countryflags/TO.png new file mode 100644 index 00000000..a7a703c9 Binary files /dev/null and b/data/countryflags/TO.png differ diff --git a/data/countryflags/TR.png b/data/countryflags/TR.png index 8bc78a72..2df563de 100644 Binary files a/data/countryflags/TR.png and b/data/countryflags/TR.png differ diff --git a/data/countryflags/TT.png b/data/countryflags/TT.png new file mode 100644 index 00000000..c3f21b2b Binary files /dev/null and b/data/countryflags/TT.png differ diff --git a/data/countryflags/TV.png b/data/countryflags/TV.png new file mode 100644 index 00000000..ede2dbca Binary files /dev/null and b/data/countryflags/TV.png differ diff --git a/data/countryflags/TW.png b/data/countryflags/TW.png new file mode 100644 index 00000000..e3c48eb2 Binary files /dev/null and b/data/countryflags/TW.png differ diff --git a/data/countryflags/TZ.png b/data/countryflags/TZ.png new file mode 100644 index 00000000..38ad129d Binary files /dev/null and b/data/countryflags/TZ.png differ diff --git a/data/countryflags/UA.png b/data/countryflags/UA.png index 1356e7cb..f9fc86cd 100644 Binary files a/data/countryflags/UA.png and b/data/countryflags/UA.png differ diff --git a/data/countryflags/UG.png b/data/countryflags/UG.png new file mode 100644 index 00000000..92537e9b Binary files /dev/null and b/data/countryflags/UG.png differ diff --git a/data/countryflags/US.png b/data/countryflags/US.png index 96dfca89..448930c2 100644 Binary files a/data/countryflags/US.png and b/data/countryflags/US.png differ diff --git a/data/countryflags/UY.png b/data/countryflags/UY.png new file mode 100644 index 00000000..4c950068 Binary files /dev/null and b/data/countryflags/UY.png differ diff --git a/data/countryflags/UZ.png b/data/countryflags/UZ.png new file mode 100644 index 00000000..0689f217 Binary files /dev/null and b/data/countryflags/UZ.png differ diff --git a/data/countryflags/VA.png b/data/countryflags/VA.png new file mode 100644 index 00000000..e957e06d Binary files /dev/null and b/data/countryflags/VA.png differ diff --git a/data/countryflags/VC.png b/data/countryflags/VC.png new file mode 100644 index 00000000..60f90b55 Binary files /dev/null and b/data/countryflags/VC.png differ diff --git a/data/countryflags/VE.png b/data/countryflags/VE.png new file mode 100644 index 00000000..e36f7a4b Binary files /dev/null and b/data/countryflags/VE.png differ diff --git a/data/countryflags/VG.png b/data/countryflags/VG.png new file mode 100644 index 00000000..99069e25 Binary files /dev/null and b/data/countryflags/VG.png differ diff --git a/data/countryflags/VI.png b/data/countryflags/VI.png new file mode 100644 index 00000000..05fa911a Binary files /dev/null and b/data/countryflags/VI.png differ diff --git a/data/countryflags/VN.png b/data/countryflags/VN.png new file mode 100644 index 00000000..c4e19d79 Binary files /dev/null and b/data/countryflags/VN.png differ diff --git a/data/countryflags/VU.png b/data/countryflags/VU.png new file mode 100644 index 00000000..228083ba Binary files /dev/null and b/data/countryflags/VU.png differ diff --git a/data/countryflags/WF.png b/data/countryflags/WF.png new file mode 100644 index 00000000..aeeba249 Binary files /dev/null and b/data/countryflags/WF.png differ diff --git a/data/countryflags/WS.png b/data/countryflags/WS.png new file mode 100644 index 00000000..5d16a5d9 Binary files /dev/null and b/data/countryflags/WS.png differ diff --git a/data/countryflags/XEN.png b/data/countryflags/XEN.png index 8388316c..08e3ef29 100644 Binary files a/data/countryflags/XEN.png and b/data/countryflags/XEN.png differ diff --git a/data/countryflags/XNI.png b/data/countryflags/XNI.png index 410615b0..18083db0 100644 Binary files a/data/countryflags/XNI.png and b/data/countryflags/XNI.png differ diff --git a/data/countryflags/XSC.png b/data/countryflags/XSC.png index f3b9ee03..3002fd50 100644 Binary files a/data/countryflags/XSC.png and b/data/countryflags/XSC.png differ diff --git a/data/countryflags/XWA.png b/data/countryflags/XWA.png index bae3809e..3b6b86be 100644 Binary files a/data/countryflags/XWA.png and b/data/countryflags/XWA.png differ diff --git a/data/countryflags/YE.png b/data/countryflags/YE.png new file mode 100644 index 00000000..73686007 Binary files /dev/null and b/data/countryflags/YE.png differ diff --git a/data/countryflags/ZA.png b/data/countryflags/ZA.png index c7e30de0..21aec1ed 100644 Binary files a/data/countryflags/ZA.png and b/data/countryflags/ZA.png differ diff --git a/data/countryflags/ZM.png b/data/countryflags/ZM.png new file mode 100644 index 00000000..2160d527 Binary files /dev/null and b/data/countryflags/ZM.png differ diff --git a/data/countryflags/ZW.png b/data/countryflags/ZW.png new file mode 100644 index 00000000..b6c870ca Binary files /dev/null and b/data/countryflags/ZW.png differ diff --git a/data/countryflags/index.txt b/data/countryflags/index.txt index f841c194..3b60f1b2 100644 --- a/data/countryflags/index.txt +++ b/data/countryflags/index.txt @@ -1,765 +1,769 @@ - -##### country codes ##### - -##### custom ##### - -default -== -1 - -XEN -== 901 - -XNI -== 902 - -XSC -== 903 - -XWA -== 904 - -##### ISO 3166-1 based ##### - -#AF -#== 4 - -#AX -#== 248 - -#AL -#== 8 - -#DZ -#== 12 - -#AS -#== 16 - -#AD -#== 20 - -#AO -#== 24 - -#AI -#== 660 - -#AQ -#== 10 - -#AG -#== 28 - -AR -== 32 - -#AM -#== 51 - -#AW -#== 533 - -AU -== 36 - -AT -== 40 - -#AZ -#== 31 - -#BS -#== 44 - -#BH -#== 48 - -#BD -#== 50 - -#BB -#== 52 - -BY -== 112 - -BE -== 56 - -#BZ -#== 84 - -#BJ -#== 204 - -#BM -#== 60 - -#BT -#== 64 - -#BO -#== 68 - -#BQ -#== 535 - -BA -== 70 - -#BW -#== 72 - -#BV -#== 74 - -BR -== 76 - -#IO -#== 86 - -#BN -#== 96 - -BG -== 100 - -#BF -#== 854 - -#BI -#== 108 - -#KH -#== 116 - -#CM -#== 120 - -CA -== 124 - -#CV -#== 132 - -#KY -#== 136 - -#CF -#== 140 - -#TD -#== 148 - -CL -== 152 - -CN -== 156 - -#CX -#== 162 - -#CC -#== 166 - -CO -== 170 - -#KM -#== 174 - -#CG -#== 178 - -#CD -#== 180 - -#CK -#== 184 - -#CR -#== 188 - -#CI -#== 384 - -HR -== 191 - -#CU -#== 192 - -#CW -#== 531 - -#CY -#== 196 - -CZ -== 203 - -DK -== 208 - -#DJ -#== 262 - -#DM -#== 212 - -#DO -#== 214 - -#EC -#== 218 - -EG -== 818 - -SV -== 222 - -#GQ -#== 226 - -#ER -#== 232 - -EE -== 233 - -#ET -#== 231 - -#FK -#== 238 - -#FO -#== 234 - -#FJ -#== 242 - -FI -== 246 - -FR -== 250 - -#GF -#== 254 - -#PF -#== 258 - -#TF -#== 260 - -#GA -#== 266 - -#GM -#== 270 - -#GE -#== 268 - -DE -== 276 - -#GH -#== 288 - -#GI -#== 292 - -GR -== 300 - -#GL -#== 304 - -#GD -#== 308 - -#GP -#== 312 - -#GU -#== 316 - -#GT -#== 320 - -#GG -#== 831 - -#GN -#== 324 - -#GW -#== 624 - -#GY -#== 328 - -#HT -#== 332 - -#HM -#== 334 - -#VA -#== 336 - -#HN -#== 340 - -#HK -#== 344 - -HU -== 348 - -#IS -#== 352 - -IN -== 356 - -ID -== 360 - -IR -== 364 - -#IQ -#== 368 - -#IE -#== 372 - -#IM -#== 833 - -IL -== 376 - -IT -== 380 - -#JM -#== 388 - -#JP -#== 392 - -#JE -#== 832 - -#JO -#== 400 - -KZ -== 398 - -#KE -#== 404 - -#KI -#== 296 - -#KP -#== 408 - -#KR -#== 410 - -#KW -#== 414 - -#KG -#== 417 - -#LA -#== 418 - -LV -== 428 - -#LB -#== 422 - -#LS -#== 426 - -#LR -#== 430 - -#LY -#== 434 - -#LI -#== 438 - -LT -== 440 - -LU -== 442 - -#MO -#== 446 - -#MK -#== 807 - -#MG -#== 450 - -#MW -#== 454 - -#MY -#== 458 - -#MV -#== 462 - -#ML -#== 466 - -#MT -#== 470 - -#MH -#== 584 - -#MQ -#== 474 - -#MR -#== 478 - -#MU -#== 480 - -#YT -#== 175 - -MX -== 484 - -#FM -#== 583 - -#MD -#== 498 - -#MC -#== 492 - -#MN -#== 496 - -#ME -#== 499 - -#MS -#== 500 - -#MA -#== 504 - -#MZ -#== 508 - -#MM -#== 104 - -#NA -#== 516 - -#NR -#== 520 - -#NP -#== 524 - -NL -== 528 - -#NC -#== 540 - -#NZ -#== 554 - -#NI -#== 558 - -#NE -#== 562 - -#NG -#== 566 - -#NU -#== 570 - -#NF -#== 574 - -#MP -#== 580 - -NO -== 578 - -#OM -#== 512 - -PK -== 586 - -#PW -#== 585 - -#PS -#== 275 - -#PA -#== 591 - -#PG -#== 598 - -#PY -#== 600 - -#PE -#== 604 - -PH -== 608 - -#PN -#== 612 - -PL -== 616 - -PT -== 620 - -#PR -#== 630 - -#QA -#== 634 - -#RE -#== 638 - -RO -== 642 - -RU -== 643 - -#RW -#== 646 - -#BL -#== 652 - -#SH -#== 654 - -#KN -#== 659 - -#LC -#== 662 - -#MF -#== 663 - -#PM -#== 666 - -#VC -#== 670 - -#WS -#== 882 - -#SM -#== 674 - -#ST -#== 678 - -SA -== 682 - -#SN -#== 686 - -RS -== 688 - -#SC -#== 690 - -#SL -#== 694 - -#SG -#== 702 - -#SX -#== 534 - -SK -== 703 - -#SI -#== 705 - -#SB -#== 90 - -#SO -#== 706 - -ZA -== 710 - -#GS -#== 239 - -ES -== 724 - -#LK -#== 144 - -#SD -#== 736 - -#SR -#== 740 - -#SJ -#== 744 - -#SZ -#== 748 - -SE -== 752 - -CH -== 756 - -#SY -#== 760 - -#TW -#== 158 - -#TJ -#== 762 - -#TZ -#== 834 - -#TH -#== 764 - -#TL -#== 626 - -#TG -#== 768 - -#TK -#== 772 - -#TO -#== 776 - -#TT -#== 780 - -#TN -#== 788 - -TR -== 792 - -#TM -#== 795 - -#TC -#== 796 - -#TV -#== 798 - -#UG -#== 800 - -UA -== 804 - -#AE -#== 784 - -GB -== 826 - -US -== 840 - -#UM -#== 581 - -#UY -#== 858 - -#UZ -#== 860 - -#VU -#== 548 - -#VE -#== 862 - -#VN -#== 704 - -#VG -#== 92 - -#VI -#== 850 - -#WF -#== 876 - -#EH -#== 732 - -#YE -#== 887 - -#ZM -#== 894 - -#ZW -#== 716 + +##### country codes ##### + +##### custom ##### + +default +== -1 + +XEN +== 901 + +XNI +== 902 + +XSC +== 903 + +XWA +== 904 + +#south sudan, non official code# +SS +== 737 + +##### ISO 3166-1 based ##### + +AF +== 4 + +AX +== 248 + +AL +== 8 + +DZ +== 12 + +AS +== 16 + +AD +== 20 + +AO +== 24 + +AI +== 660 + +#AQ +#== 10 + +AG +== 28 + +AR +== 32 + +AM +== 51 + +AW +== 533 + +AU +== 36 + +AT +== 40 + +AZ +== 31 + +BS +== 44 + +BH +== 48 + +BD +== 50 + +BB +== 52 + +BY +== 112 + +BE +== 56 + +BZ +== 84 + +BJ +== 204 + +BM +== 60 + +BT +== 64 + +BO +== 68 + +#BQ +#== 535 + +BA +== 70 + +BW +== 72 + +#BV +#== 74 + +BR +== 76 + +IO +== 86 + +BN +== 96 + +BG +== 100 + +BF +== 854 + +BI +== 108 + +KH +== 116 + +CM +== 120 + +CA +== 124 + +CV +== 132 + +KY +== 136 + +CF +== 140 + +TD +== 148 + +CL +== 152 + +CN +== 156 + +CX +== 162 + +CC +== 166 + +CO +== 170 + +KM +== 174 + +CG +== 178 + +CD +== 180 + +CK +== 184 + +CR +== 188 + +CI +== 384 + +HR +== 191 + +CU +== 192 + +CW +== 531 + +CY +== 196 + +CZ +== 203 + +DK +== 208 + +DJ +== 262 + +DM +== 212 + +DO +== 214 + +EC +== 218 + +EG +== 818 + +SV +== 222 + +GQ +== 226 + +ER +== 232 + +EE +== 233 + +ET +== 231 + +FK +== 238 + +FO +== 234 + +FJ +== 242 + +FI +== 246 + +FR +== 250 + +GF +== 254 + +PF +== 258 + +TF +== 260 + +GA +== 266 + +GM +== 270 + +GE +== 268 + +DE +== 276 + +GH +== 288 + +GI +== 292 + +GR +== 300 + +GL +== 304 + +GD +== 308 + +GP +== 312 + +GU +== 316 + +GT +== 320 + +GG +== 831 + +GN +== 324 + +GW +== 624 + +GY +== 328 + +HT +== 332 + +#HM +#== 334 + +VA +== 336 + +HN +== 340 + +HK +== 344 + +HU +== 348 + +IS +== 352 + +IN +== 356 + +ID +== 360 + +IR +== 364 + +IQ +== 368 + +IE +== 372 + +IM +== 833 + +IL +== 376 + +IT +== 380 + +JM +== 388 + +JP +== 392 + +JE +== 832 + +JO +== 400 + +KZ +== 398 + +KE +== 404 + +KI +== 296 + +KP +== 408 + +KR +== 410 + +KW +== 414 + +KG +== 417 + +LA +== 418 + +LV +== 428 + +LB +== 422 + +LS +== 426 + +LR +== 430 + +LY +== 434 + +LI +== 438 + +LT +== 440 + +LU +== 442 + +MO +== 446 + +MK +== 807 + +MG +== 450 + +MW +== 454 + +MY +== 458 + +MV +== 462 + +ML +== 466 + +MT +== 470 + +MH +== 584 + +MQ +== 474 + +MR +== 478 + +MU +== 480 + +#YT +#== 175 + +MX +== 484 + +FM +== 583 + +MD +== 498 + +MC +== 492 + +MN +== 496 + +ME +== 499 + +MS +== 500 + +MA +== 504 + +MZ +== 508 + +MM +== 104 + +NA +== 516 + +NR +== 520 + +NP +== 524 + +NL +== 528 + +NC +== 540 + +NZ +== 554 + +NI +== 558 + +NE +== 562 + +NG +== 566 + +NU +== 570 + +NF +== 574 + +MP +== 580 + +NO +== 578 + +OM +== 512 + +PK +== 586 + +PW +== 585 + +#PS +#== 275 + +PA +== 591 + +PG +== 598 + +PY +== 600 + +PE +== 604 + +PH +== 608 + +PN +== 612 + +PL +== 616 + +PT +== 620 + +PR +== 630 + +QA +== 634 + +RE +== 638 + +RO +== 642 + +RU +== 643 + +RW +== 646 + +BL +== 652 + +SH +== 654 + +KN +== 659 + +LC +== 662 + +MF +== 663 + +PM +== 666 + +VC +== 670 + +WS +== 882 + +SM +== 674 + +ST +== 678 + +SA +== 682 + +SN +== 686 + +RS +== 688 + +SC +== 690 + +SL +== 694 + +SG +== 702 + +SX +== 534 + +SK +== 703 + +SI +== 705 + +SB +== 90 + +SO +== 706 + +ZA +== 710 + +GS +== 239 + +ES +== 724 + +LK +== 144 + +SD +== 736 + +SR +== 740 + +#SJ +#== 744 + +SZ +== 748 + +SE +== 752 + +CH +== 756 + +SY +== 760 + +TW +== 158 + +TJ +== 762 + +TZ +== 834 + +TH +== 764 + +TL +== 626 + +TG +== 768 + +TK +== 772 + +TO +== 776 + +TT +== 780 + +TN +== 788 + +TR +== 792 + +TM +== 795 + +TC +== 796 + +TV +== 798 + +UG +== 800 + +UA +== 804 + +AE +== 784 + +GB +== 826 + +US +== 840 + +#UM +#== 581 + +UY +== 858 + +UZ +== 860 + +VU +== 548 + +VE +== 862 + +VN +== 704 + +VG +== 92 + +VI +== 850 + +WF +== 876 + +EH +== 732 + +YE +== 887 + +ZM +== 894 + +ZW +== 716 -- cgit 1.4.1 From 5f4a5b3366aebf55abc1112d9cac8325d3f082ce Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 12 Jul 2011 20:33:53 +0200 Subject: added country flags to language selectors --- data/languages/index.txt | 21 ++++++++++++ src/game/client/components/menus_settings.cpp | 46 +++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/data/languages/index.txt b/data/languages/index.txt index 3e8d9f91..3a0c3a34 100644 --- a/data/languages/index.txt +++ b/data/languages/index.txt @@ -3,63 +3,84 @@ bosnian == Bosanski +== 70 brazilian_portuguese == Português brasileiro +== 76 bulgarian == Български +== 100 czech == Česky +== 203 danish == Dansk +== 208 dutch == Nederlands +== 528 finnish == Suomi +== 246 french == Français +== 250 german == Deutsch +== 276 italian == Italiano +== 380 norwegian == Norsk +== 578 polish == Polski +== 616 portuguese == Português +== 620 romanian == Română +== 642 russian == Русский +== 643 serbian == Srpski +== 688 slovak == Slovensky +== 703 spanish == Español +== 724 swedish == Svenska +== 752 turkish == Türkçe +== 792 ukrainian == Українська +== 804 diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 3fb0ab94..c2fab00f 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -812,10 +812,11 @@ class CLanguage { public: CLanguage() {} - CLanguage(const char *n, const char *f) : m_Name(n), m_FileName(f) {} + CLanguage(const char *n, const char *f, int Code) : m_Name(n), m_FileName(f), m_CountryCode(Code) {} string m_Name; string m_FileName; + int m_CountryCode; bool operator<(const CLanguage &Other) { return m_Name < Other.m_Name; } }; @@ -830,6 +831,7 @@ void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array< } char aOrigin[128]; + char aReplacement[128]; CLineReader LineReader; LineReader.Init(File); char *pLine; @@ -839,14 +841,32 @@ void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array< continue; str_copy(aOrigin, pLine, sizeof(aOrigin)); - char *pReplacement = LineReader.Get(); - if(!pReplacement) + + pLine = LineReader.Get(); + if(!pLine) + { + pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", "unexpected end of index file"); + break; + } + + if(pLine[0] != '=' || pLine[1] != '=' || pLine[2] != ' ') + { + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin); + pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf); + (void)LineReader.Get(); + continue; + } + str_copy(aReplacement, pLine+3, sizeof(aReplacement)); + + pLine = LineReader.Get(); + if(!pLine) { pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", "unexpected end of index file"); break; } - if(pReplacement[0] != '=' || pReplacement[1] != '=' || pReplacement[2] != ' ') + if(pLine[0] != '=' || pLine[1] != '=' || pLine[2] != ' ') { char aBuf[128]; str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin); @@ -856,7 +876,7 @@ void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array< char aFileName[128]; str_format(aFileName, sizeof(aFileName), "languages/%s.txt", aOrigin); - pLanguages->add(CLanguage(pReplacement+3, aFileName)); + pLanguages->add(CLanguage(aReplacement, aFileName, str_toint(pLine+3))); } io_close(File); } @@ -870,7 +890,7 @@ void CMenus::RenderLanguageSelection(CUIRect MainView) if(s_Languages.size() == 0) { - s_Languages.add(CLanguage("English", "")); + s_Languages.add(CLanguage("English", "", 826)); LoadLanguageIndexfile(Storage(), Console(), &s_Languages); for(int i = 0; i < s_Languages.size(); i++) if(str_comp(s_Languages[i].m_FileName, g_Config.m_ClLanguagefile) == 0) @@ -889,7 +909,19 @@ void CMenus::RenderLanguageSelection(CUIRect MainView) CListboxItem Item = UiDoListboxNextItem(&r.front()); if(Item.m_Visible) - UI()->DoLabelScaled(&Item.m_Rect, r.front().m_Name, 16.0f, -1); + { + CUIRect Rect; + Item.m_Rect.VSplitLeft(Item.m_Rect.h*2.0f, &Rect, &Item.m_Rect); + Rect.VMargin(6.0f, &Rect); + Rect.HMargin(3.0f, &Rect); + Graphics()->TextureSet(m_pClient->m_pCountryFlags->GetByCountryCode(r.front().m_CountryCode)->m_Texture); + Graphics()->QuadsBegin(); + IGraphics::CQuadItem QuadItem(Rect.x, Rect.y, Rect.w, Rect.h); + Graphics()->QuadsDrawTL(&QuadItem, 1); + Graphics()->QuadsEnd(); + Item.m_Rect.HSplitTop(2.0f, 0, &Item.m_Rect); + UI()->DoLabelScaled(&Item.m_Rect, r.front().m_Name, 16.0f, -1); + } } s_SelectedLanguage = UiDoListboxEnd(&s_ScrollValue, 0); -- cgit 1.4.1 From 7a129caf8d3ad7fe0f3f5a94bd2d9ffce08d4942 Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 13 Jul 2011 23:09:19 +0200 Subject: added updated jungle_main rules by Landil --- data/editor/jungle_main.rules | 62 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/data/editor/jungle_main.rules b/data/editor/jungle_main.rules index 3b967020..ada1f3ac 100644 --- a/data/editor/jungle_main.rules +++ b/data/editor/jungle_main.rules @@ -8,14 +8,14 @@ Pos 0 1 FULL Pos 0 -1 FULL Pos 1 0 FULL Pos -1 0 FULL -Random 150 +Random 200 Index 67 Pos 0 1 FULL Pos 0 -1 FULL Pos 1 0 FULL Pos -1 0 FULL -Random 150 +Random 200 #top Index 16 @@ -23,15 +23,15 @@ Pos 0 -1 EMPTY Index 96 Pos 0 -1 EMPTY -Random 4 +Random 15 Index 97 Pos 0 -1 EMPTY -Random 4 +Random 15 Index 98 Pos 0 -1 EMPTY -Random 4 +Random 15 #right Index 21 @@ -43,15 +43,15 @@ Pos 0 1 EMPTY Index 99 Pos 0 1 EMPTY -Random 4 +Random 10 Index 100 Pos 0 1 EMPTY -Random 4 +Random 10 Index 101 Pos 0 1 EMPTY -Random 4 +Random 10 #left Index 21 XFLIP @@ -72,35 +72,81 @@ Index 37 XFLIP Pos 0 1 EMPTY Pos -1 0 EMPTY +Index 39 XFLIP +Pos 0 1 EMPTY +Pos -1 0 EMPTY +Random 2 + #corner bottom-right Index 37 Pos 0 1 EMPTY Pos 1 0 EMPTY +Index 39 +Pos 0 1 EMPTY +Pos 1 0 EMPTY +Random 2 + #inside corner top-right Index 54 Pos -1 1 EMPTY Pos -1 0 FULL Pos 0 1 FULL +Index 53 XFLIP +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL +Random 2 + #inside corner top-left Index 54 XFLIP Pos 1 1 EMPTY Pos 1 0 FULL Pos 0 1 FULL +Index 53 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL +Random 2 + #inside corner bottom-left Index 48 XFLIP Pos 1 -1 EMPTY Pos 1 0 FULL Pos 0 -1 FULL +Index 49 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL +Random 3 + +Index 50 YFLIP +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL +Random 3 + #inside corner bottom-right Index 48 Pos -1 -1 EMPTY Pos -1 0 FULL Pos 0 -1 FULL +Index 49 XFLIP +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL +Random 3 + +Index 51 YFLIP +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL +Random 3 + #right bottom Index 22 Pos -1 0 EMPTY -- cgit 1.4.1 From 571dff6216562387ff020407c147fe8000177c15 Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 14 Jul 2011 22:07:21 +0200 Subject: made rcon auto completion serverside. Closes #97 --- scripts/cmd5.py | 2 +- src/engine/client.h | 1 + src/engine/client/client.cpp | 24 ++++- src/engine/client/client.h | 4 +- src/engine/console.h | 24 ++++- src/engine/server/server.cpp | 95 +++++++++++++++--- src/engine/server/server.h | 9 ++ src/engine/shared/console.cpp | 171 ++++++++++++++++++++++++++++++--- src/engine/shared/console.h | 18 +++- src/engine/shared/protocol.h | 6 +- src/game/client/components/console.cpp | 30 ++++-- src/game/client/components/console.h | 5 +- src/game/server/gamecontext.cpp | 32 +++--- 13 files changed, 356 insertions(+), 65 deletions(-) diff --git a/scripts/cmd5.py b/scripts/cmd5.py index a06d45a7..07e35bb1 100644 --- a/scripts/cmd5.py +++ b/scripts/cmd5.py @@ -30,6 +30,6 @@ for filename in sys.argv[1:]: hash = hashlib.md5(f).hexdigest().lower()[16:] #TODO 0.7: improve nethash creation -if hash == "5c1e637ffddf3a37": +if hash == "71de0f4d82688970": hash = "626fce9a778df4d4" print('#define GAME_NETVERSION_HASH "%s"' % hash) diff --git a/src/engine/client.h b/src/engine/client.h index 65ab761e..966e8f61 100644 --- a/src/engine/client.h +++ b/src/engine/client.h @@ -95,6 +95,7 @@ public: // remote console virtual void RconAuth(const char *pUsername, const char *pPassword) = 0; virtual bool RconAuthed() = 0; + virtual bool UseTempRconCommands() = 0; virtual void Rcon(const char *pLine) = 0; // server info diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 6949c308..90131703 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -536,11 +536,6 @@ void CClient::SendReady() SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH); } -bool CClient::RconAuthed() -{ - return m_RconAuthed; -} - void CClient::RconAuth(const char *pName, const char *pPassword) { if(RconAuthed()) @@ -549,6 +544,7 @@ void CClient::RconAuth(const char *pName, const char *pPassword) CMsgPacker Msg(NETMSG_RCON_AUTH); Msg.AddString(pName, 32); Msg.AddString(pPassword, 32); + Msg.AddInt(1); SendMsgEx(&Msg, MSGFLAG_VITAL); } @@ -726,6 +722,7 @@ void CClient::DisconnectWithReason(const char *pReason) // m_RconAuthed = 0; + m_pConsole->DeregisterTempAll(); m_NetClient.Disconnect(pReason); SetState(IClient::STATE_OFFLINE); m_pMap->Unload(); @@ -1313,11 +1310,28 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) CMsgPacker Msg(NETMSG_PING_REPLY); SendMsgEx(&Msg, 0); } + else if(Msg == NETMSG_RCON_CMD_ADD) + { + const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); + const char *pHelp = Unpacker.GetString(CUnpacker::SANITIZE_CC); + const char *pParams = Unpacker.GetString(CUnpacker::SANITIZE_CC); + if(Unpacker.Error() == 0) + m_pConsole->RegisterTemp(pName, pParams, CFGFLAG_SERVER, pHelp); + } + else if(Msg == NETMSG_RCON_CMD_REM) + { + const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); + if(Unpacker.Error() == 0) + m_pConsole->DeregisterTemp(pName); + } else if(Msg == NETMSG_RCON_AUTH_STATUS) { int Result = Unpacker.GetInt(); if(Unpacker.Error() == 0) m_RconAuthed = Result; + m_UseTempRconCommands = Unpacker.GetInt(); + if(Unpacker.Error() != 0) + m_UseTempRconCommands = 0; } else if(Msg == NETMSG_RCON_LINE) { diff --git a/src/engine/client/client.h b/src/engine/client/client.h index fa0ddaf7..3d81f073 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -128,6 +128,7 @@ class CClient : public IClient, public CDemoPlayer::IListner int m_AckGameTick; int m_CurrentRecvTick; int m_RconAuthed; + int m_UseTempRconCommands; // version-checking char m_aVersionStr[10]; @@ -220,7 +221,8 @@ public: void SendEnterGame(); void SendReady(); - virtual bool RconAuthed(); + virtual bool RconAuthed() { return m_RconAuthed != 0; } + virtual bool UseTempRconCommands() { return m_UseTempRconCommands != 0; } void RconAuth(const char *pName, const char *pPassword); virtual void Rcon(const char *pCmd); diff --git a/src/engine/console.h b/src/engine/console.h index e650ac47..7c39cf49 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -10,6 +10,7 @@ class IConsole : public IInterface MACRO_INTERFACE("console", 0) public: + // TODO: rework/cleanup enum { OUTPUT_LEVEL_STANDARD=0, @@ -18,6 +19,10 @@ public: ACCESS_LEVEL_ADMIN=0, ACCESS_LEVEL_MOD, + + TEMPCMD_NAME_LENGTH=32, + TEMPCMD_HELP_LENGTH=64, + TEMPCMD_PARAMS_LENGTH=16, }; // TODO: rework this interface to reduce the amount of virtual calls @@ -38,10 +43,18 @@ public: class CCommandInfo { + protected: + int m_AccessLevel; public: + CCommandInfo() { m_AccessLevel = ACCESS_LEVEL_ADMIN; } + virtual ~CCommandInfo() {} const char *m_pName; const char *m_pHelp; const char *m_pParams; + + virtual const CCommandInfo *NextCommandInfo(int AccessLevel, int FlagMask) const = 0; + + int GetAccessLevel() const { return m_AccessLevel; } }; typedef void (*FPrintCallback)(const char *pStr, void *pUser); @@ -49,12 +62,15 @@ public: typedef void (*FCommandCallback)(IResult *pResult, void *pUserData); typedef void (*FChainCommandCallback)(IResult *pResult, void *pUserData, FCommandCallback pfnCallback, void *pCallbackUserData); - virtual CCommandInfo *GetCommandInfo(const char *pName, int FlagMask) = 0; - virtual void PossibleCommands(const char *pStr, int FlagMask, FPossibleCallback pfnCallback, void *pUser) = 0; + virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int Flagmask) const = 0; + virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp) = 0; + virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser) = 0; virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0; - virtual void Register(const char *pName, const char *pParams, - int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0; + virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0; + virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) = 0; + virtual void DeregisterTemp(const char *pName) = 0; + virtual void DeregisterTempAll() = 0; virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0; virtual void StoreCommands(bool Store) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 24d3b317..17df19ed 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -580,6 +580,7 @@ int CServer::NewClientCallback(int ClientID, void *pUser) pThis->m_aClients[ClientID].m_Country = -1; pThis->m_aClients[ClientID].m_Authed = AUTHED_NO; pThis->m_aClients[ClientID].m_AuthTries = 0; + pThis->m_aClients[ClientID].m_pRconCmdToSend = 0; pThis->m_aClients[ClientID].Reset(); return 0; } @@ -605,6 +606,7 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) pThis->m_aClients[ClientID].m_Country = -1; pThis->m_aClients[ClientID].m_Authed = AUTHED_NO; pThis->m_aClients[ClientID].m_AuthTries = 0; + pThis->m_aClients[ClientID].m_pRconCmdToSend = 0; pThis->m_aClients[ClientID].m_Snapshots.PurgeAll(); return 0; } @@ -649,6 +651,37 @@ void CServer::SendRconLineAuthed(const char *pLine, void *pUser) ReentryGuard--; } +void CServer::SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID) +{ + CMsgPacker Msg(NETMSG_RCON_CMD_ADD); + Msg.AddString(pCommandInfo->m_pName, 32); + Msg.AddString(pCommandInfo->m_pHelp, 64); + Msg.AddString(pCommandInfo->m_pParams, 16); + SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); +} + +void CServer::SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID) +{ + CMsgPacker Msg(NETMSG_RCON_CMD_REM); + Msg.AddString(pCommandInfo->m_pName, 256); + SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); +} + +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; + for(int i = 0; i < MAX_RCONCMD_SEND && m_aClients[ClientID].m_pRconCmdToSend; ++i) + { + SendRconCmdAdd(m_aClients[ClientID].m_pRconCmdToSend, ClientID); + m_aClients[ClientID].m_pRconCmdToSend = m_aClients[ClientID].m_pRconCmdToSend->NextCommandInfo(ConsoleAccessLevel, CFGFLAG_SERVER); + } + } +} + void CServer::ProcessClientPacket(CNetChunk *pPacket) { int ClientID = pPacket->m_ClientID; @@ -843,10 +876,14 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) else if(g_Config.m_SvRconPassword[0] && str_comp(pPw, g_Config.m_SvRconPassword) == 0) { CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); - Msg.AddInt(1); + Msg.AddInt(1); //authed + Msg.AddInt(1); //cmdlist SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); m_aClients[ClientID].m_Authed = AUTHED_ADMIN; + int SendRconCmds = Unpacker.GetInt(); + if(Unpacker.Error() == 0 && SendRconCmds) + m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_ADMIN, CFGFLAG_SERVER); SendRconLine(ClientID, "Admin authentication successful. Full remote console access granted."); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (admin)", ClientID); @@ -855,10 +892,14 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) else if(g_Config.m_SvRconModPassword[0] && str_comp(pPw, g_Config.m_SvRconModPassword) == 0) { CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); - Msg.AddInt(1); + Msg.AddInt(1); //authed + Msg.AddInt(1); //cmdlist SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); m_aClients[ClientID].m_Authed = AUTHED_MOD; + int SendRconCmds = Unpacker.GetInt(); + if(Unpacker.Error() == 0 && SendRconCmds) + m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_MOD, CFGFLAG_SERVER); SendRconLine(ClientID, "Moderator authentication successful. Limited remote console access granted."); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (moderator)", ClientID); @@ -1243,6 +1284,8 @@ int CServer::Run() { if(g_Config.m_SvHighBandwidth || (m_CurrentGameTick%2) == 0) DoSnapshot(); + + UpdateClientRconCommands(); } // master server stuff @@ -1512,26 +1555,56 @@ void CServer::ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pU ((CServer *)pUserData)->m_NetServer.SetMaxClientsPerIP(pResult->GetInteger(0)); } +void CServer::ConchainModCommandUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + if(pResult->NumArguments() == 2) + { + CServer *pThis = static_cast(pUserData); + const IConsole::CCommandInfo *pInfo = pThis->Console()->GetCommandInfo(pResult->GetString(0), CFGFLAG_SERVER, false); + int OldAccessLevel; + if(pInfo) + OldAccessLevel = pInfo->GetAccessLevel(); + pfnCallback(pResult, pCallbackUserData); + if(pInfo && OldAccessLevel != pInfo->GetAccessLevel()) + { + for(int i = 0; i < MAX_CLIENTS; ++i) + { + if(pThis->m_aClients[i].m_State == CServer::CClient::STATE_EMPTY || pThis->m_aClients[i].m_Authed != CServer::AUTHED_MOD || + (pThis->m_aClients[i].m_pRconCmdToSend && str_comp(pResult->GetString(0), pThis->m_aClients[i].m_pRconCmdToSend->m_pName) >= 0)) + continue; + + if(OldAccessLevel == IConsole::ACCESS_LEVEL_ADMIN) + pThis->SendRconCmdAdd(pInfo, i); + else + pThis->SendRconCmdRem(pInfo, i); + } + } + } + else + pfnCallback(pResult, pCallbackUserData); +} + void CServer::RegisterCommands() { m_pConsole = Kernel()->RequestInterface(); - Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, ""); - Console()->Register("ban", "s?ir", CFGFLAG_SERVER|CFGFLAG_STORE, ConBan, this, ""); - Console()->Register("unban", "s", CFGFLAG_SERVER|CFGFLAG_STORE, ConUnban, this, ""); - Console()->Register("bans", "", CFGFLAG_SERVER|CFGFLAG_STORE, ConBans, this, ""); - Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, ""); - Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, ""); + 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("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"); - Console()->Register("record", "?s", CFGFLAG_SERVER|CFGFLAG_STORE, ConRecord, this, ""); - Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, ""); + Console()->Register("record", "?s", CFGFLAG_SERVER|CFGFLAG_STORE, ConRecord, this, "Record to a file"); + Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, "Stop recording"); - Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, ""); + Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, "Reload the map"); Console()->Chain("sv_name", ConchainSpecialInfoupdate, this); Console()->Chain("password", ConchainSpecialInfoupdate, this); Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this); + Console()->Chain("mod_command", ConchainModCommandUpdate, this); } diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 72c82d4d..5b6e038d 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -54,6 +54,8 @@ public: AUTHED_NO=0, AUTHED_MOD, AUTHED_ADMIN, + + MAX_RCONCMD_SEND=16, }; class CClient @@ -100,6 +102,8 @@ public: int m_Authed; int m_AuthTries; + const IConsole::CCommandInfo *m_pRconCmdToSend; + void Reset(); }; @@ -169,6 +173,10 @@ public: void SendRconLine(int ClientID, const char *pLine); static void SendRconLineAuthed(const char *pLine, void *pUser); + void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID); + void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID); + void UpdateClientRconCommands(); + void ProcessClientPacket(CNetChunk *pPacket); void SendServerInfo(NETADDR *pAddr, int Token); @@ -197,6 +205,7 @@ public: static void ConMapReload(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); void RegisterCommands(); diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 588abd61..847fb140 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -33,6 +33,29 @@ float CConsole::CResult::GetFloat(unsigned Index) return str_tofloat(m_apArgs[Index]); } +const IConsole::CCommandInfo *CConsole::CCommand::NextCommandInfo(int AccessLevel, int FlagMask) const +{ + const CCommand *pInfo = m_pNext; + while(pInfo) + { + if(pInfo->m_Flags&FlagMask && pInfo->m_AccessLevel >= AccessLevel) + break; + pInfo = pInfo->m_pNext; + } + return pInfo; +} + +const IConsole::CCommandInfo *CConsole::FirstCommandInfo(int AccessLevel, int FlagMask) const +{ + for(const CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) + { + if(pCommand->m_Flags&FlagMask && pCommand->GetAccessLevel() >= AccessLevel) + return pCommand; + } + + return 0; +} + // the maximum number of tokens occurs in a string of length CONSOLE_MAX_STR_LENGTH with tokens size 1 separated by single spaces @@ -258,7 +281,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) if(pCommand) { - if(pCommand->m_AccessLevel >= m_AccessLevel) + if(pCommand->GetAccessLevel() >= m_AccessLevel) { int IsStrokeCommand = 0; if(Result.m_pCommand[0] == '+') @@ -305,11 +328,11 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) } } -void CConsole::PossibleCommands(const char *pStr, int FlagMask, FPossibleCallback pfnCallback, void *pUser) +void CConsole::PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser) { for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) { - if(pCommand->m_Flags&FlagMask) + if(pCommand->m_Flags&FlagMask && pCommand->m_Temp == Temp) { if(str_find_nocase(pCommand->m_pName, pStr)) pfnCallback(pCommand->m_pName, pUser); @@ -403,11 +426,11 @@ void CConsole::ConModCommandAccess(IResult *pResult, void *pUser) { if(pResult->NumArguments() == 2) { - pCommand->m_AccessLevel = clamp(pResult->GetInteger(1), (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_MOD)); - str_format(aBuf, sizeof(aBuf), "moderator access for '%s' is now %s", pResult->GetString(0), pCommand->m_AccessLevel ? "enabled" : "disabled"); + pCommand->SetAccessLevel(pResult->GetInteger(1)); + str_format(aBuf, sizeof(aBuf), "moderator access for '%s' is now %s", pResult->GetString(0), pCommand->GetAccessLevel() ? "enabled" : "disabled"); } else - str_format(aBuf, sizeof(aBuf), "moderator access for '%s' is %s", pResult->GetString(0), pCommand->m_AccessLevel ? "enabled" : "disabled"); + str_format(aBuf, sizeof(aBuf), "moderator access for '%s' is %s", pResult->GetString(0), pCommand->GetAccessLevel() ? "enabled" : "disabled"); } else str_format(aBuf, sizeof(aBuf), "No such command: '%s'.", pResult->GetString(0)); @@ -424,7 +447,7 @@ void CConsole::ConModCommandStatus(IResult *pResult, void *pUser) for(CCommand *pCommand = pConsole->m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) { - if(pCommand->m_Flags&pConsole->m_FlagMask && pCommand->m_AccessLevel == ACCESS_LEVEL_MOD) + if(pCommand->m_Flags&pConsole->m_FlagMask && pCommand->GetAccessLevel() == ACCESS_LEVEL_MOD) { int Length = str_length(pCommand->m_pName); if(Used + Length + 2 < (int)(sizeof(aBuf))) @@ -531,6 +554,8 @@ CConsole::CConsole(int FlagMask) { m_FlagMask = FlagMask; m_AccessLevel = ACCESS_LEVEL_ADMIN; + m_pRecycleList = 0; + m_TempCommands.Reset(); m_StoreCommands = true; m_paStrokeStr[0] = "0"; m_paStrokeStr[1] = "1"; @@ -592,20 +617,131 @@ 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 && m_pFirstCommand->m_pNext) + pCommand->m_pNext = m_pFirstCommand; + else + pCommand->m_pNext = 0; + m_pFirstCommand = pCommand; + } + else + { + 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) + { + pCommand->m_pNext = p->m_pNext; + p->m_pNext = pCommand; + break; + } + } + } +} + 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; pCommand->m_pfnCallback = pfnFunc; pCommand->m_pUserData = pUser; - pCommand->m_pHelp = pHelp; + pCommand->m_pName = pName; + pCommand->m_pHelp = pHelp; pCommand->m_pParams = pParams; + + pCommand->m_Flags = Flags; + pCommand->m_Temp = false; + + AddCommandSorted(pCommand); +} + +void CConsole::RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) +{ + CCommand *pCommand; + if(m_pRecycleList) + { + pCommand = m_pRecycleList; + str_copy(const_cast(pCommand->m_pName), pName, TEMPCMD_NAME_LENGTH); + str_copy(const_cast(pCommand->m_pHelp), pHelp, TEMPCMD_HELP_LENGTH); + str_copy(const_cast(pCommand->m_pParams), pParams, TEMPCMD_PARAMS_LENGTH); + + m_pRecycleList = m_pRecycleList->m_pNext; + } + else + { + pCommand = new(m_TempCommands.Allocate(sizeof(CCommand))) CCommand; + char *pMem = static_cast(m_TempCommands.Allocate(TEMPCMD_NAME_LENGTH)); + str_copy(pMem, pName, TEMPCMD_NAME_LENGTH); + pCommand->m_pName = pMem; + pMem = static_cast(m_TempCommands.Allocate(TEMPCMD_HELP_LENGTH)); + str_copy(pMem, pHelp, TEMPCMD_HELP_LENGTH); + pCommand->m_pHelp = pMem; + pMem = static_cast(m_TempCommands.Allocate(TEMPCMD_PARAMS_LENGTH)); + str_copy(pMem, pParams, TEMPCMD_PARAMS_LENGTH); + pCommand->m_pParams = pMem; + } + + pCommand->m_pfnCallback = 0; + pCommand->m_pUserData = 0; pCommand->m_Flags = Flags; - pCommand->m_AccessLevel = ACCESS_LEVEL_ADMIN; + pCommand->m_Temp = true; + + AddCommandSorted(pCommand); +} + +void CConsole::DeregisterTemp(const char *pName) +{ + if(!m_pFirstCommand) + return; + + CCommand *pRemoved = 0; + + // remove temp entry from command list + if(m_pFirstCommand->m_Temp && str_comp(m_pFirstCommand->m_pName, pName) == 0) + { + pRemoved = m_pFirstCommand; + m_pFirstCommand = m_pFirstCommand->m_pNext; + } + else + { + for(CCommand *pCommand = m_pFirstCommand; pCommand->m_pNext; pCommand = pCommand->m_pNext) + if(pCommand->m_pNext->m_Temp && str_comp(pCommand->m_pNext->m_pName, pName) == 0) + { + pRemoved = pCommand->m_pNext; + pCommand->m_pNext = pCommand->m_pNext->m_pNext; + break; + } + } + + // add to recycle list + if(pRemoved) + { + pRemoved->m_pNext = m_pRecycleList; + m_pRecycleList = pRemoved; + } +} + +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) + { + CCommand *pNext = pCommand->m_pNext; + if(pNext->m_Temp) + { + for(; pNext && pNext->m_Temp; pNext = pNext->m_pNext); + pCommand->m_pNext = pNext; + } + } - pCommand->m_pNext = m_pFirstCommand; - m_pFirstCommand = pCommand; + m_TempCommands.Reset(); + m_pRecycleList = 0; } void CConsole::Con_Chain(IResult *pResult, void *pUserData) @@ -651,9 +787,18 @@ void CConsole::StoreCommands(bool Store) } -IConsole::CCommandInfo *CConsole::GetCommandInfo(const char *pName, int FlagMask) +const IConsole::CCommandInfo *CConsole::GetCommandInfo(const char *pName, int FlagMask, bool Temp) { - return FindCommand(pName, FlagMask); + for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext) + { + if(pCommand->m_Flags&FlagMask && pCommand->m_Temp == Temp) + { + if(str_comp_nocase(pCommand->m_pName, pName) == 0) + return pCommand; + } + } + + return 0; } diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 14c48581..b29f3202 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -13,9 +13,13 @@ class CConsole : public IConsole public: CCommand *m_pNext; int m_Flags; - int m_AccessLevel; + bool m_Temp; FCommandCallback m_pfnCallback; void *m_pUserData; + + virtual const CCommandInfo *NextCommandInfo(int AccessLevel, int FlagMask) const; + + void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_MOD)); } }; @@ -44,6 +48,9 @@ class CConsole : public IConsole class IStorage *m_pStorage; int m_AccessLevel; + CCommand *m_pRecycleList; + CHeap m_TempCommands; + static void Con_Chain(IResult *pResult, void *pUserData); static void Con_Echo(IResult *pResult, void *pUserData); static void Con_Exec(IResult *pResult, void *pUserData); @@ -138,16 +145,21 @@ class CConsole : public IConsole } } m_ExecutionQueue; + void AddCommandSorted(CCommand *pCommand); CCommand *FindCommand(const char *pName, int FlagMask); public: CConsole(int FlagMask); - virtual CCommandInfo *GetCommandInfo(const char *pName, int FlagMask); - virtual void PossibleCommands(const char *pStr, int FlagMask, FPossibleCallback pfnCallback, void *pUser) ; + 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); virtual void ParseArguments(int NumArgs, const char **ppArguments); virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp); + virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp); + virtual void DeregisterTemp(const char *pName); + virtual void DeregisterTempAll(); virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser); virtual void StoreCommands(bool Store); diff --git a/src/engine/shared/protocol.h b/src/engine/shared/protocol.h index 4a4895ad..ba04da8a 100644 --- a/src/engine/shared/protocol.h +++ b/src/engine/shared/protocol.h @@ -65,7 +65,11 @@ enum // sent by both NETMSG_PING, NETMSG_PING_REPLY, - NETMSG_ERROR + NETMSG_ERROR, + + // sent by server (todo: move it up) + NETMSG_RCON_CMD_ADD, + NETMSG_RCON_CMD_REM, }; // this should be revised diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index 2f5c49ad..9b16ce0d 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -51,7 +51,7 @@ CGameConsole::CInstance::CInstance(int Type) m_CompletionChosen = -1; m_CompletionRenderOffset = 0.0f; - m_pCommand = 0x0; + m_IsCommand = false; } void CGameConsole::CInstance::Init(CGameConsole *pGameConsole) @@ -147,14 +147,16 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event) { m_CompletionChosen++; m_CompletionEnumerationCount = 0; - m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, PossibleCommandsCompleteCallback, this); + m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL && + m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands(), PossibleCommandsCompleteCallback, this); // handle wrapping if(m_CompletionEnumerationCount && m_CompletionChosen >= m_CompletionEnumerationCount) { m_CompletionChosen %= m_CompletionEnumerationCount; m_CompletionEnumerationCount = 0; - m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, PossibleCommandsCompleteCallback, this); + m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL && + m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands(), PossibleCommandsCompleteCallback, this); } } } @@ -190,7 +192,17 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event) aBuf[i] = *pSrc; aBuf[i] = 0; - m_pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf, m_CompletionFlagmask); + const IConsole::CCommandInfo *pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf, m_CompletionFlagmask, + m_Type != CGameConsole::CONSOLETYPE_LOCAL && m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands()); + if(pCommand) + { + m_IsCommand = true; + str_copy(m_aCommandName, pCommand->m_pName, IConsole::TEMPCMD_NAME_LENGTH); + str_copy(m_aCommandHelp, pCommand->m_pHelp, IConsole::TEMPCMD_HELP_LENGTH); + str_copy(m_aCommandParams, pCommand->m_pParams, IConsole::TEMPCMD_PARAMS_LENGTH); + } + else + m_IsCommand = false; } } } @@ -449,19 +461,19 @@ void CGameConsole::OnRender() { if(pConsole->m_Input.GetString()[0] != 0) { - m_pConsole->PossibleCommands(pConsole->m_aCompletionBuffer, pConsole->m_CompletionFlagmask, PossibleCommandsRenderCallback, &Info); + m_pConsole->PossibleCommands(pConsole->m_aCompletionBuffer, pConsole->m_CompletionFlagmask, m_ConsoleType != CGameConsole::CONSOLETYPE_LOCAL && + Client()->RconAuthed() && Client()->UseTempRconCommands(), PossibleCommandsRenderCallback, &Info); pConsole->m_CompletionRenderOffset = Info.m_Offset; if(Info.m_EnumCount <= 0) { - if(pConsole->m_pCommand) + if(pConsole->m_IsCommand) { - char aBuf[512]; - str_format(aBuf, sizeof(aBuf), "Help: %s ", pConsole->m_pCommand->m_pHelp); + str_format(aBuf, sizeof(aBuf), "Help: %s ", pConsole->m_aCommandHelp); TextRender()->TextEx(&Info.m_Cursor, aBuf, -1); TextRender()->TextColor(0.75f, 0.75f, 0.75f, 1); - str_format(aBuf, sizeof(aBuf), "Syntax: %s %s", pConsole->m_pCommand->m_pName, pConsole->m_pCommand->m_pParams); + str_format(aBuf, sizeof(aBuf), "Syntax: %s %s", pConsole->m_aCommandName, pConsole->m_aCommandParams); TextRender()->TextEx(&Info.m_Cursor, aBuf, -1); } } diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h index 003a9423..326fb076 100644 --- a/src/game/client/components/console.h +++ b/src/game/client/components/console.h @@ -33,7 +33,10 @@ class CGameConsole : public CComponent int m_CompletionFlagmask; float m_CompletionRenderOffset; - IConsole::CCommandInfo *m_pCommand; + bool m_IsCommand; + char m_aCommandName[IConsole::TEMPCMD_NAME_LENGTH]; + char m_aCommandHelp[IConsole::TEMPCMD_HELP_LENGTH]; + char m_aCommandParams[IConsole::TEMPCMD_PARAMS_LENGTH]; CInstance(int t); void Init(CGameConsole *pGameConsole); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 52eaca89..6b029bbd 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1317,22 +1317,22 @@ void CGameContext::OnConsoleInit() m_pServer = Kernel()->RequestInterface(); m_pConsole = Kernel()->RequestInterface(); - Console()->Register("tune", "si", CFGFLAG_SERVER, ConTuneParam, this, ""); - Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, ""); - Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, ""); - - Console()->Register("change_map", "?r", CFGFLAG_SERVER|CFGFLAG_STORE, ConChangeMap, this, ""); - Console()->Register("restart", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConRestart, this, ""); - Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, ""); - Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, ""); - Console()->Register("set_team", "ii?i", CFGFLAG_SERVER, ConSetTeam, this, ""); - Console()->Register("set_team_all", "i", CFGFLAG_SERVER, ConSetTeamAll, this, ""); - - Console()->Register("add_vote", "sr", CFGFLAG_SERVER, ConAddVote, this, ""); - Console()->Register("remove_vote", "s", CFGFLAG_SERVER, ConRemoveVote, this, ""); - Console()->Register("force_vote", "ss?r", CFGFLAG_SERVER, ConForceVote, this, ""); - Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, ""); - Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, ""); + Console()->Register("tune", "si", CFGFLAG_SERVER, ConTuneParam, this, "Tune variable to value"); + Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "Reset tuning"); + Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, "Dump tuning"); + + Console()->Register("change_map", "?r", CFGFLAG_SERVER|CFGFLAG_STORE, ConChangeMap, this, "Change map"); + Console()->Register("restart", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConRestart, this, "Restart in x seconds"); + Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "Broadcast message"); + Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "Say in chat"); + Console()->Register("set_team", "ii?i", CFGFLAG_SERVER, ConSetTeam, this, "Set team of player to team"); + Console()->Register("set_team_all", "i", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team"); + + Console()->Register("add_vote", "sr", CFGFLAG_SERVER, ConAddVote, this, "Add a voting option"); + Console()->Register("remove_vote", "s", CFGFLAG_SERVER, ConRemoveVote, this, "remove a voting option"); + Console()->Register("force_vote", "ss?r", CFGFLAG_SERVER, ConForceVote, this, "Force a voting option"); + Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "Clears the voting options"); + Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "Force a vote to yes/no"); Console()->Chain("sv_motd", ConchainSpecialMotdupdate, this); } -- cgit 1.4.1 From 0765c29c15b9f18dfef2355b8824cb7ff1ad2b2f Mon Sep 17 00:00:00 2001 From: TeeWorlds-org Date: Mon, 11 Jul 2011 12:44:41 -0700 Subject: Edited data/languages/czech.txt via GitHub --- data/languages/czech.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/languages/czech.txt b/data/languages/czech.txt index 83d657a1..5d50f47a 100644 --- a/data/languages/czech.txt +++ b/data/languages/czech.txt @@ -26,7 +26,7 @@ == Zbývá sekund: %i %s wins! -== %s zvítězil! +== Vítězí %s! -Page %d- == -Strana %d- @@ -398,7 +398,7 @@ Player == Hráč Player country: -== Národnost hráče: +== Národnost: Player options == Nastavení hráčů @@ -551,7 +551,7 @@ Spectate next == Pozorovat dalšího Spectate previous -== Pozorovat předchozího +== Pozorovat minulého Spectator mode == Nastavit pozorování @@ -584,7 +584,7 @@ Team chat == Týmový chat Teeworlds %s is out! Download it at www.teeworlds.com! -== Vyšlo nové Teeworlds %s! Stáhněte si ji na www.teeworlds.com! +== Stáhněte si nové Teeworlds %s na www.teeworlds.com! Texture Compression == Komprimované textury -- cgit 1.4.1 From 35f17e71343f2b46f46138befb7203802b84150c Mon Sep 17 00:00:00 2001 From: HeroiAmarelo Date: Tue, 12 Jul 2011 02:52:48 -0700 Subject: Edited data/languages/portuguese.txt via GitHub --- data/languages/portuguese.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index 8d830608..a122104e 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -1,4 +1,3 @@ - ##### translated strings ##### %d Bytes @@ -293,7 +292,7 @@ Lht. == Luz Loading -== Carregando +== Aguarda por favor MOTD == MOTD -- cgit 1.4.1 From 5058ec732febfafd7eb9819df19072ed863dfed8 Mon Sep 17 00:00:00 2001 From: drnickxyz Date: Thu, 14 Jul 2011 11:26:06 -0700 Subject: Edited data/languages/serbian.txt via GitHub --- data/languages/serbian.txt | 145 ++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/data/languages/serbian.txt b/data/languages/serbian.txt index 64c8fb37..693d14ed 100644 --- a/data/languages/serbian.txt +++ b/data/languages/serbian.txt @@ -1,4 +1,3 @@ - ##### translated strings ##### %d of %d servers, %d players @@ -460,220 +459,220 @@ Your skin ##### needs translation ##### %d Bytes -== +== %d Bytes %d%% loaded -== +== Učitano %d%% %i minute left -== +== Još %ds %i minutes left -== +== Preostalo: %i min. %i second left -== +== Preostalo: %i min. %i seconds left -== +== Preostalo: %i sek. %s wins! -== +== %s je pobijedio! -Page %d- -== +== -Strana %d- Add -== +== Dodaj Add Friend -== +== Dodaj prijatelja Are you sure that you want to delete the demo? -== +== Da li sigurni da želite da obrišete demo-snimak? Are you sure that you want to remove the player from your friends list? -== +== Da li ste sigurni da želite da obrišete igrača iz liste prijatelja? Automatically record demos -== +== Automatski snimi demo Automatically take game over screenshot -== +== Automatski napravi screenshot Change settings -== +== Izmeni podešavanja Clan -== +== Klan Client -== +== Klijent Count players only -== +== Izbroj samo igrače Country -== +== Država Crc: -== +== Crc: Created: -== +== Kreirano: Delete demo -== +== Obriši demo-snimak Demo details -== +== Detalji demo-a Demofile: %s -== +== Demo-snimak: %s Folder -== +== Direktorijum Free-View -== +== Slobodan pregled Friends -== +== Prijatelji Invalid Demo -== +== Neispravan demo-snimak Kick player -== +== Izbaci igrača iz igre Length: -== +== Dužina: Map: -== +== Mapa: Max Screenshots -== +== Maksimalan broj screenshot-ova Max demos -== +== Maksimalan broj demo-a Move player to spectators -== +== Prebaci igrača u posmatrače Name plates size -== +== Veličina pozadine za ime Netversion: -== +== Net-verzija: New name: -== +== Novo ime: Open -== +== Otvori Parent Folder -== +== Prethodni direktorijum Play background music -== +== Pozadinska muzika Player country: -== +== Država Player options -== +== Podešavanja igrača Quit anyway? -== +== Izlaz? REC %3d:%02d -== +== REC %3d:%02d Reason: -== +== Razlog: Record demo -== +== Snimi demo Remove -== +== Ukloni Remove friend -== +== Ukloni prijatelja Rename -== +== Preimenuj Rename demo -== +== Preimenuj demo-snimak Server address: -== +== Adresa servera: Server filter -== +== Filter servera Show friends only -== +== Prikaži isključivo prijatelje Show ingame HUD -== +== Prikaži HUD Size: -== +== Veličina: Sound error -== +== Problem sa zvukom Spectate next -== +== Posmatraj narednog Spectate previous -== +== Posmatraj prethodnog Spectator mode -== +== Posmatrački mod Stop record -== +== Prekini snimanje Strict gametype filter -== +== Striktan filter tipa igre The audio device couldn't be initialised. -== +== Audio-uređaj nije moguće pokrenuti. There's an unsaved map in the editor, you might want to save it before you quit the game. -== +== Mapa u editoru nije zapamćena, možda želite da je zapamtite pre izlaska iz igre. Time limit: %d min -== +== Vremensko ograničenje: %d min. Type: -== +== Tip: Unable to delete the demo -== +== Demo-snimak nije moguće obrisati Unable to rename the demo -== +== Demo-snimak nije moguće preimenovati Use team colors for name plates -== +== Koristi timsku boju u prikazu imena Version: -== +== Verzija: Vote command: -== +== Komanda za glasanje: Vote description: -== +== Opis glasanja: no limit -== +== bez ograničenja ##### old translations ##### -- cgit 1.4.1 From a3fec2f9f384f82ec631bbfc43bce456b20a2e0e Mon Sep 17 00:00:00 2001 From: SushiTee Date: Tue, 12 Jul 2011 05:26:52 +0200 Subject: fixed clipping on some machines --- src/engine/client/graphics.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/engine/client/graphics.cpp b/src/engine/client/graphics.cpp index 76fd3400..d1f0b8a8 100644 --- a/src/engine/client/graphics.cpp +++ b/src/engine/client/graphics.cpp @@ -179,7 +179,16 @@ CGraphics_OpenGL::CGraphics_OpenGL() void CGraphics_OpenGL::ClipEnable(int x, int y, int w, int h) { - //if(no_gfx) return; + if(x < 0) + w += x; + if(y < 0) + h += y; + + x = clamp(x, 0, ScreenWidth()); + y = clamp(y, 0, ScreenHeight()); + w = clamp(w, 0, ScreenWidth()-x); + h = clamp(h, 0, ScreenHeight()-y); + glScissor(x, ScreenHeight()-(y+h), w, h); glEnable(GL_SCISSOR_TEST); } -- cgit 1.4.1 From d78c0d66e5108f0316f3bcac2a2119aa3a680ff9 Mon Sep 17 00:00:00 2001 From: SushiTee Date: Tue, 12 Jul 2011 03:14:46 +0200 Subject: ability to name groups and layers --- src/game/editor/editor.cpp | 125 +++++++++++++++++++++++++++++++--------- src/game/editor/editor.h | 10 ++-- src/game/editor/io.cpp | 28 ++++++++- src/game/editor/layer_game.cpp | 2 +- src/game/editor/layer_quads.cpp | 2 +- src/game/editor/layer_tiles.cpp | 2 +- src/game/editor/popups.cpp | 26 ++++++++- src/game/mapitems.h | 8 ++- 8 files changed, 163 insertions(+), 40 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 94a5d837..630bad8d 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -41,7 +41,7 @@ CEditorImage::~CEditorImage() CLayerGroup::CLayerGroup() { - m_pName = ""; + m_aName[0] = 0; m_Visible = true; m_SaveToMap = true; m_GameGroup = false; @@ -196,32 +196,59 @@ void CEditorImage::AnalyseTileFlags() // copied from gc_menu.cpp, should be more generalized //extern int ui_do_edit_box(void *id, const CUIRect *rect, char *str, int str_size, float font_size, bool hidden=false); -int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden) +int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden, int Corners) { - int Inside = UI()->MouseInside(pRect); + int Inside = UI()->MouseInside(pRect); bool ReturnValue = false; + bool UpdateOffset = false; static int s_AtIndex = 0; + static bool s_DoScroll = false; + static float s_ScrollStart = 0.0f; + + FontSize *= UI()->Scale(); if(UI()->LastActiveItem() == pID) { int Len = str_length(pStr); + if(Len == 0) + s_AtIndex = 0; if(Inside && UI()->MouseButton(0)) { + s_DoScroll = true; + s_ScrollStart = UI()->MouseX(); int MxRel = (int)(UI()->MouseX() - pRect->x); - for (int i = 1; i <= Len; i++) + for(int i = 1; i <= Len; i++) { - if (TextRender()->TextWidth(0, FontSize, pStr, i) + 10 > MxRel) + if(TextRender()->TextWidth(0, FontSize, pStr, i) - *Offset > MxRel) { s_AtIndex = i - 1; break; } - if (i == Len) + if(i == Len) s_AtIndex = Len; } } + else if(!UI()->MouseButton(0)) + s_DoScroll = false; + else if(s_DoScroll) + { + // do scrolling + if(UI()->MouseX() < pRect->x && s_ScrollStart-UI()->MouseX() > 10.0f) + { + s_AtIndex = max(0, s_AtIndex-1); + s_ScrollStart = UI()->MouseX(); + UpdateOffset = true; + } + else if(UI()->MouseX() > pRect->x+pRect->w && UI()->MouseX()-s_ScrollStart > 10.0f) + { + s_AtIndex = min(Len, s_AtIndex+1); + s_ScrollStart = UI()->MouseX(); + UpdateOffset = true; + } + } for(int i = 0; i < Input()->NumEvents(); i++) { @@ -235,7 +262,11 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str if(UI()->ActiveItem() == pID) { if(!UI()->MouseButton(0)) + { + s_AtIndex = min(s_AtIndex, str_length(pStr)); + s_DoScroll = false; UI()->SetActiveItem(0); + } } else if(UI()->HotItem() == pID) { @@ -251,8 +282,8 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str UI()->SetHotItem(pID); CUIRect Textbox = *pRect; - RenderTools()->DrawUIRect(&Textbox, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 3.0f); - Textbox.VMargin(3.0f, &Textbox); + RenderTools()->DrawUIRect(&Textbox, vec4(1, 1, 1, 0.5f), Corners, 3.0f); + Textbox.VMargin(2.0f, &Textbox); const char *pDisplayStr = pStr; char aStars[128]; @@ -268,19 +299,47 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str pDisplayStr = aStars; } + // check if the text has to be moved + if(UI()->LastActiveItem() == pID && !JustGotActive && (UpdateOffset || Input()->NumEvents())) + { + float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex); + if(w-*Offset > Textbox.w) + { + // move to the left + float wt = TextRender()->TextWidth(0, FontSize, pDisplayStr, -1); + do + { + *Offset += min(wt-*Offset-Textbox.w, Textbox.w/3); + } + while(w-*Offset > Textbox.w); + } + else if(w-*Offset < 0.0f) + { + // move to the right + do + { + *Offset = max(0.0f, *Offset-Textbox.w/3); + } + while(w-*Offset < 0.0f); + } + } + UI()->ClipEnable(pRect); + Textbox.x -= *Offset; + UI()->DoLabel(&Textbox, pDisplayStr, FontSize, -1); - - //TODO: make it blink + + // render the cursor if(UI()->LastActiveItem() == pID && !JustGotActive) { float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex); Textbox = *pRect; Textbox.VSplitLeft(2.0f, 0, &Textbox); - Textbox.x += w*UI()->Scale(); - Textbox.y -= FontSize/10.f; - - UI()->DoLabel(&Textbox, "|", FontSize*1.1f, -1); + Textbox.x += (w-*Offset-TextRender()->TextWidth(0, FontSize, "|", -1)/2); + + if((2*time_get()/time_freq()) % 2) // make it blink + UI()->DoLabel(&Textbox, "|", FontSize, -1); } + UI()->ClipDisable(); return ReturnValue; } @@ -443,12 +502,12 @@ int CEditor::DoButton_Tab(const void *pID, const char *pText, int Checked, const 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) +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.y += NewRect.h/2.0f-7.0f; - UI()->DoLabel(&NewRect, pText, 10, 0, -1); + 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); } @@ -1951,16 +2010,19 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) if(!m_Map.m_lGroups[g]->m_GameGroup) m_Map.m_lGroups[g]->m_SaveToMap = !m_Map.m_lGroups[g]->m_SaveToMap; - str_format(aBuf, sizeof(aBuf),"#%d %s", g, m_Map.m_lGroups[g]->m_pName); + str_format(aBuf, sizeof(aBuf),"#%d %s", g, m_Map.m_lGroups[g]->m_aName); + float FontSize = 10.0f; + while(TextRender()->TextWidth(0, FontSize, aBuf, -1) > Slot.w) + FontSize--; if(int Result = DoButton_Ex(&m_Map.m_lGroups[g], aBuf, g==m_SelectedGroup, &Slot, - BUTTON_CONTEXT, "Select group. Right click for properties.", 0)) + BUTTON_CONTEXT, "Select group. Right click for properties.", 0, FontSize)) { m_SelectedGroup = g; m_SelectedLayer = 0; static int s_GroupPopupId = 0; if(Result == 2) - UiInvokePopupMenu(&s_GroupPopupId, 0, UI()->MouseX(), UI()->MouseY(), 120, 200, PopupGroup); + UiInvokePopupMenu(&s_GroupPopupId, 0, UI()->MouseX(), UI()->MouseY(), 120, 220, PopupGroup); } LayersBox.HSplitTop(2.0f, &Slot, &LayersBox); } @@ -1989,9 +2051,18 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) if(m_Map.m_lGroups[g]->m_lLayers[i] != m_Map.m_pGameLayer) m_Map.m_lGroups[g]->m_lLayers[i]->m_SaveToMap = !m_Map.m_lGroups[g]->m_lLayers[i]->m_SaveToMap; - str_format(aBuf, sizeof(aBuf),"#%d %s ", i, m_Map.m_lGroups[g]->m_lLayers[i]->m_pTypeName); + if(m_Map.m_lGroups[g]->m_lLayers[i]->m_aName[0]) + str_format(aBuf, sizeof(aBuf), "%s", m_Map.m_lGroups[g]->m_lLayers[i]->m_aName); + else if(m_Map.m_lGroups[g]->m_lLayers[i]->m_Type == LAYERTYPE_TILES) + str_copy(aBuf, "Tiles", sizeof(aBuf)); + else + str_copy(aBuf, "Quads", sizeof(aBuf)); + + float FontSize = 10.0f; + while(TextRender()->TextWidth(0, FontSize, aBuf, -1) > Button.w) + FontSize--; if(int Result = DoButton_Ex(m_Map.m_lGroups[g]->m_lLayers[i], aBuf, g==m_SelectedGroup&&i==m_SelectedLayer, &Button, - BUTTON_CONTEXT, "Select layer. Right click for properties.", 0)) + BUTTON_CONTEXT, "Select layer. Right click for properties.", 0, FontSize)) { m_SelectedLayer = i; m_SelectedGroup = g; @@ -2382,9 +2453,9 @@ void CEditor::RenderFileDialog() // filebox if(m_FileDialogStorageType == IStorage::TYPE_SAVE) { - static int s_FileBoxID = 0; + static float s_FileBoxID = 0; UI()->DoLabel(&FileBoxLabel, "Filename:", 10.0f, -1, -1); - if(DoEditBox(&s_FileBoxID, &FileBox, m_aFileDialogFileName, sizeof(m_aFileDialogFileName), 10.0f)) + if(DoEditBox(&s_FileBoxID, &FileBox, m_aFileDialogFileName, sizeof(m_aFileDialogFileName), 10.0f, &s_FileBoxID)) { // remove '/' and '\' for(int i = 0; m_aFileDialogFileName[i]; ++i) @@ -2733,8 +2804,8 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) ToolBar.VSplitLeft(80.0f, &Button, &ToolBar); - static int s_NameBox = 0; - if(DoEditBox(&s_NameBox, &Button, pEnvelope->m_aName, sizeof(pEnvelope->m_aName), 10.0f)) + static float s_NameBox = 0; + if(DoEditBox(&s_NameBox, &Button, pEnvelope->m_aName, sizeof(pEnvelope->m_aName), 10.0f, &s_NameBox)) m_Map.m_Modified = true; } } @@ -3385,7 +3456,7 @@ void CEditorMap::MakeGameGroup(CLayerGroup *pGroup) { m_pGameGroup = pGroup; m_pGameGroup->m_GameGroup = true; - m_pGameGroup->m_pName = "Game"; + str_copy(m_pGameGroup->m_aName, "Game", sizeof(m_pGameGroup->m_aName)); } diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 92ec7b2b..1139562e 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -126,7 +126,7 @@ public: CLayer() { m_Type = LAYERTYPE_INVALID; - m_pTypeName = "(invalid)"; + str_copy(m_aName, "(invalid)", sizeof(m_aName)); m_Visible = true; m_Readonly = false; m_SaveToMap = true; @@ -156,7 +156,7 @@ public: virtual void GetSize(float *w, float *h) { *w = 0; *h = 0;} - const char *m_pTypeName; + char m_aName[12]; int m_Type; int m_Flags; @@ -184,7 +184,7 @@ public: int m_ClipW; int m_ClipH; - const char *m_pName; + char m_aName[12]; bool m_GameGroup; bool m_Visible; bool m_SaveToMap; @@ -667,7 +667,7 @@ public: int DoButton_Editor(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_Tab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); - int DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners); + int DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize=10.0f); int DoButton_ButtonDec(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_ButtonInc(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); @@ -676,7 +676,7 @@ public: int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_MenuItem(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags=0, const char *pToolTip=0); - int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden=false); + int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden=false, int Corners=CUI::CORNER_ALL); void RenderBackground(CUIRect View, int Texture, float Size, float Brightness); diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 987404b8..9ce6d1f1 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -266,6 +266,9 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) GItem.m_StartLayer = LayerCount; GItem.m_NumLayers = 0; + // save group name + StrToInts(GItem.m_aName, sizeof(GItem.m_aName)/sizeof(int), pGroup->m_aName); + for(int l = 0; l < pGroup->m_lLayers.size(); l++) { if(!pGroup->m_lLayers[l]->m_SaveToMap) @@ -278,7 +281,7 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) pLayer->PrepareForSave(); CMapItemLayerTilemap Item; - Item.m_Version = 2; + Item.m_Version = 3; Item.m_Layer.m_Flags = pLayer->m_Flags; Item.m_Layer.m_Type = pLayer->m_Type; @@ -295,6 +298,10 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) Item.m_Flags = pLayer->m_Game; Item.m_Image = pLayer->m_Image; Item.m_Data = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTile), pLayer->m_pTiles); + + // save layer name + StrToInts(Item.m_aName, sizeof(Item.m_aName)/sizeof(int), pLayer->m_aName); + df.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item); GItem.m_NumLayers++; @@ -307,7 +314,7 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) if(pLayer->m_lQuads.size()) { CMapItemLayerQuads Item; - Item.m_Version = 1; + Item.m_Version = 2; Item.m_Layer.m_Flags = pLayer->m_Flags; Item.m_Layer.m_Type = pLayer->m_Type; Item.m_Image = pLayer->m_Image; @@ -315,6 +322,10 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) // add the data Item.m_NumQuads = pLayer->m_lQuads.size(); Item.m_Data = df.AddDataSwapped(pLayer->m_lQuads.size()*sizeof(CQuad), pLayer->m_lQuads.base_ptr()); + + // save layer name + StrToInts(Item.m_aName, sizeof(Item.m_aName)/sizeof(int), pLayer->m_aName); + df.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item); // clean up @@ -489,6 +500,10 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag pGroup->m_ClipH = pGItem->m_ClipH; } + // load group name + if(pGItem->m_Version >= 3) + IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName)/sizeof(int), pGroup->m_aName); + for(int l = 0; l < pGItem->m_NumLayers; l++) { CLayer *pLayer = 0; @@ -524,6 +539,10 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag pTiles->m_Image = pTilemapItem->m_Image; pTiles->m_Game = pTilemapItem->m_Flags&1; + // load layer name + if(pTilemapItem->m_Version >= 3) + IntsToStr(pTilemapItem->m_aName, sizeof(pTiles->m_aName)/sizeof(int), pTiles->m_aName); + mem_copy(pTiles->m_pTiles, pData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile)); if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) @@ -546,6 +565,11 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag pQuads->m_Image = pQuadsItem->m_Image; if(pQuads->m_Image < -1 || pQuads->m_Image >= m_lImages.size()) pQuads->m_Image = -1; + + // load layer name + if(pQuadsItem->m_Version >= 2) + IntsToStr(pQuadsItem->m_aName, sizeof(pQuads->m_aName)/sizeof(int), pQuads->m_aName); + void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data); pGroup->AddLayer(pQuads); pQuads->m_lQuads.set_size(pQuadsItem->m_NumQuads); diff --git a/src/game/editor/layer_game.cpp b/src/game/editor/layer_game.cpp index f4a5fb76..7e879c3e 100644 --- a/src/game/editor/layer_game.cpp +++ b/src/game/editor/layer_game.cpp @@ -6,7 +6,7 @@ CLayerGame::CLayerGame(int w, int h) : CLayerTiles(w, h) { - m_pTypeName = "Game"; + str_copy(m_aName, "Game", sizeof(m_aName)); m_Game = 1; } diff --git a/src/game/editor/layer_quads.cpp b/src/game/editor/layer_quads.cpp index d2a8a1e5..a0c0d544 100644 --- a/src/game/editor/layer_quads.cpp +++ b/src/game/editor/layer_quads.cpp @@ -13,7 +13,7 @@ CLayerQuads::CLayerQuads() { m_Type = LAYERTYPE_QUADS; - m_pTypeName = "Quads"; + str_copy(m_aName, "Quads", sizeof(m_aName)); m_Image = -1; } diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index 81944636..ebaa640a 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -15,7 +15,7 @@ CLayerTiles::CLayerTiles(int w, int h) { m_Type = LAYERTYPE_TILES; - m_pTypeName = "Tiles"; + str_copy(m_aName, "Tiles", sizeof(m_aName)); m_Width = w; m_Height = h; m_Image = -1; diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 0a691fdf..00c9f043 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -167,6 +167,17 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View) return 1; } + // group name + if(!pEditor->GetSelectedGroup()->m_GameGroup) + { + View.HSplitBottom(5.0f, &View, &Button); + View.HSplitBottom(12.0f, &View, &Button); + static float s_Name = 0; + pEditor->UI()->DoLabel(&Button, "Name:", 10.0f, -1, -1); + Button.VSplitLeft(40.0f, 0, &Button); + pEditor->DoEditBox(&s_Name, &Button, pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_aName, sizeof(pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_aName), 10.0f, &s_Name); + } + enum { PROP_ORDER=0, @@ -243,6 +254,17 @@ int CEditor::PopupLayer(CEditor *pEditor, CUIRect View) return 1; } + // layer name + if(pEditor->m_Map.m_pGameLayer != pEditor->GetSelectedLayer(0)) + { + View.HSplitBottom(5.0f, &View, &Button); + View.HSplitBottom(12.0f, &View, &Button); + static float s_Name = 0; + pEditor->UI()->DoLabel(&Button, "Name:", 10.0f, -1, -1); + Button.VSplitLeft(40.0f, 0, &Button); + pEditor->DoEditBox(&s_Name, &Button, pEditor->GetSelectedLayer(0)->m_aName, sizeof(pEditor->GetSelectedLayer(0)->m_aName), 10.0f, &s_Name); + } + View.HSplitBottom(10.0f, &View, 0); CLayerGroup *pCurrentGroup = pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]; @@ -532,8 +554,8 @@ int CEditor::PopupNewFolder(CEditor *pEditor, CUIRect View) View.HSplitBottom(40.0f, &View, 0); View.VMargin(40.0f, &View); View.HSplitBottom(20.0f, &View, &Label); - static int s_FolderBox = 0; - pEditor->DoEditBox(&s_FolderBox, &Label, pEditor->m_FileDialogNewFolderName, sizeof(pEditor->m_FileDialogNewFolderName), 15.0f); + static float s_FolderBox = 0; + pEditor->DoEditBox(&s_FolderBox, &Label, pEditor->m_FileDialogNewFolderName, sizeof(pEditor->m_FileDialogNewFolderName), 15.0f, &s_FolderBox); View.HSplitBottom(20.0f, &View, &Label); pEditor->UI()->DoLabel(&Label, "Name:", 10.0f, -1); diff --git a/src/game/mapitems.h b/src/game/mapitems.h index d99d6724..4daf139b 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -114,13 +114,15 @@ struct CMapItemGroup_v1 struct CMapItemGroup : public CMapItemGroup_v1 { - enum { CURRENT_VERSION=2 }; + enum { CURRENT_VERSION=3 }; int m_UseClipping; int m_ClipX; int m_ClipY; int m_ClipW; int m_ClipH; + + int m_aName[3]; } ; struct CMapItemLayer @@ -145,6 +147,8 @@ struct CMapItemLayerTilemap int m_Image; int m_Data; + + int m_aName[3]; } ; struct CMapItemLayerQuads @@ -155,6 +159,8 @@ struct CMapItemLayerQuads int m_NumQuads; int m_Data; int m_Image; + + int m_aName[3]; } ; struct CMapItemVersion -- cgit 1.4.1 From ef881a532147c512b08faedf34b982ce6ebc1921 Mon Sep 17 00:00:00 2001 From: SushiTee Date: Tue, 12 Jul 2011 18:38:33 +0200 Subject: added layer/image scrolling via mouse wheel --- src/game/editor/editor.cpp | 47 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 630bad8d..8e1c81ec 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -840,13 +840,6 @@ void CEditor::DoToolbar(CUIRect ToolBar) m_AnimateSpeed -= 0.5f; } - if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP) && m_Dialog == DIALOG_NONE) - m_ZoomLevel -= 20; - - if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN) && m_Dialog == DIALOG_NONE) - m_ZoomLevel += 20; - - m_ZoomLevel = clamp(m_ZoomLevel, 50, 2000); m_WorldZoom = m_ZoomLevel/100.0f; TB_Top.VSplitLeft(10.0f, &Button, &TB_Top); @@ -1976,6 +1969,20 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) LayersBox.VSplitRight(3.0f, &LayersBox, 0); // extra spacing Scroll.HMargin(5.0f, &Scroll); s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + + if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&LayersBox)) + { + int ScrollNum = (int)((LayersHeight-LayersBox.h)/15.0f)+1; + if(ScrollNum > 0) + { + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) + s_ScrollValue = clamp(s_ScrollValue - 1.0f/ScrollNum, 0.0f, 1.0f); + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) + s_ScrollValue = clamp(s_ScrollValue + 1.0f/ScrollNum, 0.0f, 1.0f); + } + else + ScrollNum = 0; + } } float LayerStartAt = ScrollDifference * s_ScrollValue; @@ -2272,6 +2279,20 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) ToolBox.VSplitRight(3.0f, &ToolBox, 0); // extra spacing Scroll.HMargin(5.0f, &Scroll); s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + + if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&ToolBox)) + { + int ScrollNum = (int)((ImagesHeight-ToolBox.h)/14.0f)+1; + if(ScrollNum > 0) + { + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) + s_ScrollValue = clamp(s_ScrollValue - 1.0f/ScrollNum, 0.0f, 1.0f); + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) + s_ScrollValue = clamp(s_ScrollValue + 1.0f/ScrollNum, 0.0f, 1.0f); + } + else + ScrollNum = 0; + } } float ImageStartAt = ScrollDifference * s_ScrollValue; @@ -3264,6 +3285,18 @@ void CEditor::Render() if(m_Mode == MODE_LAYERS) DoMapEditor(View, ToolBar); + // do the scrolling + if(m_Dialog == DIALOG_NONE && UI()->MouseInside(&View)) + { + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) + m_ZoomLevel -= 20; + + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) + m_ZoomLevel += 20; + + m_ZoomLevel = clamp(m_ZoomLevel, 50, 2000); + } + if(m_GuiActive) { float Brightness = 0.25f; -- cgit 1.4.1 From f7a9e80163af47ef4ad1bc9df1cf635610ebe2eb Mon Sep 17 00:00:00 2001 From: SushiTee Date: Tue, 12 Jul 2011 17:54:59 +0200 Subject: added possibility to collapse groups by double clicking them --- src/game/editor/editor.cpp | 19 +++++++++++++++---- src/game/editor/editor.h | 1 + src/game/editor/popups.cpp | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 8e1c81ec..ecb38444 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -44,6 +44,7 @@ CLayerGroup::CLayerGroup() m_aName[0] = 0; m_Visible = true; m_SaveToMap = true; + m_Collapse = false; m_GameGroup = false; m_OffsetX = 0; m_OffsetY = 0; @@ -1956,9 +1957,13 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) static float s_ScrollValue = 0; for(int g = 0; g < m_Map.m_lGroups.size(); g++) + { // Each group is 19.0f // Each layer is 14.0f - LayersHeight += 19.0f + m_Map.m_lGroups[g]->m_lLayers.size() * 14.0f; + LayersHeight += 19.0f; + if(!m_Map.m_lGroups[g]->m_Collapse) + LayersHeight += m_Map.m_lGroups[g]->m_lLayers.size() * 14.0f; + } float ScrollDifference = LayersHeight - LayersBox.h; @@ -2009,7 +2014,7 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) { LayersBox.HSplitTop(12.0f, &Slot, &LayersBox); Slot.VSplitLeft(12, &VisibleToggle, &Slot); - if(DoButton_Ex(&m_Map.m_lGroups[g]->m_Visible, m_Map.m_lGroups[g]->m_Visible?"V":"H", 0, &VisibleToggle, 0, "Toggle group visibility", CUI::CORNER_L)) + if(DoButton_Ex(&m_Map.m_lGroups[g]->m_Visible, m_Map.m_lGroups[g]->m_Visible?"V":"H", m_Map.m_lGroups[g]->m_Collapse ? 1 : 0, &VisibleToggle, 0, "Toggle group visibility", CUI::CORNER_L)) m_Map.m_lGroups[g]->m_Visible = !m_Map.m_lGroups[g]->m_Visible; Slot.VSplitRight(12.0f, &Slot, &SaveCheck); @@ -2022,7 +2027,7 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) while(TextRender()->TextWidth(0, FontSize, aBuf, -1) > Slot.w) FontSize--; if(int Result = DoButton_Ex(&m_Map.m_lGroups[g], aBuf, g==m_SelectedGroup, &Slot, - BUTTON_CONTEXT, "Select group. Right click for properties.", 0, FontSize)) + BUTTON_CONTEXT, m_Map.m_lGroups[g]->m_Collapse ? "Select group. Double click to expand." : "Select group. Double click to collapse.", 0, FontSize)) { m_SelectedGroup = g; m_SelectedLayer = 0; @@ -2030,6 +2035,9 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) static int s_GroupPopupId = 0; if(Result == 2) UiInvokePopupMenu(&s_GroupPopupId, 0, UI()->MouseX(), UI()->MouseY(), 120, 220, PopupGroup); + + if(m_Map.m_lGroups[g]->m_lLayers.size() && Input()->MouseDoubleClick()) + m_Map.m_lGroups[g]->m_Collapse ^= 1; } LayersBox.HSplitTop(2.0f, &Slot, &LayersBox); } @@ -2045,6 +2053,9 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) continue; } + if(m_Map.m_lGroups[g]->m_Collapse) + continue; + //visible LayersBox.HSplitTop(12.0f, &Slot, &LayersBox); Slot.VSplitLeft(12.0f, 0, &Button); @@ -2069,7 +2080,7 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) while(TextRender()->TextWidth(0, FontSize, aBuf, -1) > Button.w) FontSize--; if(int Result = DoButton_Ex(m_Map.m_lGroups[g]->m_lLayers[i], aBuf, g==m_SelectedGroup&&i==m_SelectedLayer, &Button, - BUTTON_CONTEXT, "Select layer. Right click for properties.", 0, FontSize)) + BUTTON_CONTEXT, "Select layer.", 0, FontSize)) { m_SelectedLayer = i; m_SelectedGroup = g; diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 1139562e..d282f5e1 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -188,6 +188,7 @@ public: bool m_GameGroup; bool m_Visible; bool m_SaveToMap; + bool m_Collapse; CLayerGroup(); ~CLayerGroup(); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 00c9f043..d8b8a91e 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -151,6 +151,7 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View) l->m_pEditor = pEditor; pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->AddLayer(l); pEditor->m_SelectedLayer = pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_lLayers.size()-1; + pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_Collapse = false; return 1; } @@ -164,6 +165,7 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View) l->m_pEditor = pEditor; pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->AddLayer(l); pEditor->m_SelectedLayer = pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_lLayers.size()-1; + pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_Collapse = false; return 1; } -- cgit 1.4.1 From 932ac835d3b30367d265a4a66cffdb5efd9e1974 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 15 Jul 2011 01:09:59 +0200 Subject: added update for Italian translation by Apmox --- data/languages/italian.txt | 235 +++++++++++------------ data/languages/portuguese.txt | 1 + data/languages/serbian.txt | 431 +++++++++++++++++++++--------------------- 3 files changed, 336 insertions(+), 331 deletions(-) diff --git a/data/languages/italian.txt b/data/languages/italian.txt index 4e81ec97..d566da49 100644 --- a/data/languages/italian.txt +++ b/data/languages/italian.txt @@ -2,31 +2,31 @@ ##### translated strings ##### %d Bytes -== %d Bytes +== %d byte %d of %d servers, %d players -== %d di %d servers, %d giocatori +== %d di %d server, %d giocatori %d%% loaded == %d%% caricato %ds left -== %ds rimanenti +== %ds sec. %i minute left -== %i minuto residuo +== %i minuto rimanente %i minutes left -== %i minuti residui +== %i minuti rimanenti %i second left -== %i secondo residuo +== %i secondo rimanente %i seconds left -== %i secondi residui +== %i secondi rimanenti %s wins! -== %s vittorie! +== %s ha vinto! -Page %d- == -Pagina %d- @@ -38,7 +38,7 @@ Add == Aggiungi Add Friend -== Aggiungi Amico +== Aggiungi amico Address == Indirizzo @@ -50,25 +50,25 @@ Alpha == Alpha Always show name plates -== Mostra sempre nomi +== Mostra sempre i nomi Are you sure that you want to delete the demo? == Sicuro di voler eliminare la demo? Are you sure that you want to quit? -== Sicuro di voler uscire? +== Sicuro di voler chiudere il gioco? Are you sure that you want to remove the player from your friends list? -== Sicuro di voler rimuovere il giocatore dalla lista degli amici? +== Sicuro di voler rimuovere il giocatore dalla lista di amici? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== E' la prima volta che avvii il gioco, inserisci il tuo nickname. E' bene che tu controlli le opzioni prima di giocare per avere una migliore esperienza di gioco. +== Essendo la prima volta che avvii il gioco, ti preghiamo di inserire il tuo nickname qui sotto. Puoi cambiare le impostazioni in base alle tue preferenze prima di entrare in gioco. Automatically record demos == Registra automaticamente demo Automatically take game over screenshot -== Cattura automaticamente la schermata 'game over' +== Cattura schermata alla fine di ogni partita Blue team == Squadra blu @@ -80,10 +80,10 @@ Body == Corpo Call vote -== Chiama voto +== Vota Change settings -== Cambia configurazione +== Cambia opzioni Chat == Chat @@ -113,7 +113,7 @@ Console == Console Controls -== Controlli +== Comandi Count players only == Conta solo giocatori @@ -125,7 +125,7 @@ Crc: == Crc: Created: -== Creato: +== Creata: Current == Attuale @@ -145,6 +145,9 @@ Delete demo Demo details == Dettagli demo +Demofile: %s +== Demo: %s + Demos == Demo @@ -155,13 +158,13 @@ Disconnected == Disconnesso Display Modes -== Modalità Display +== Risoluzioni schermo Downloading map -== Scaricamento mappa +== Scaricamento mappa in corso Draw! -== Patta! +== Pareggio! Dynamic Camera == Camera dinamica @@ -203,58 +206,58 @@ Force vote == Forza voto Free-View -== Camera libera +== Visione libera Friends == Amici Fullscreen -== A tutto schermo +== Schermo intero Game == Partita Game info -== Informazioni partita +== Info partita Game over -== Fine partita +== Partita finita Game type -== Modalità di gioco +== Tipo Game types: -== Modalità di gioco: +== Tipo di gioco: General == Generale Graphics -== Gráfica +== Aspetto Grenade -== Granata +== Lanciagranate Hammer == Martello Has people playing -== Contiene giocatori +== Con giocatori High Detail -== Alta Risoluzione +== Alta qualità Hook == Rampino Host address -== Indirizzo Host +== Indirizzo host Hue == Tinta Info -== Informazioni +== Info Internet == Internet @@ -263,19 +266,19 @@ Invalid Demo == Demo non valida Join blue -== Unisciti ai blu +== Vai ai blu Join game -== Unisciti alla partita +== Entra Join red -== Unisciti ai rossi +== Vai ai rossi Jump == Salta Kick player -== Espelli giocatore +== Caccia giocatore LAN == LAN @@ -284,7 +287,7 @@ Language == Lingua Length: -== Lunghezza: +== Durata: Lht. == Luminosità @@ -302,10 +305,10 @@ Map: == Mappa: Max Screenshots -== Screenshot Massimi +== Numero massimo di catture Max demos -== Demo massime +== Numero massimo di demo Maximum ping: == Ping massimo: @@ -314,13 +317,13 @@ Miscellaneous == Altro Mouse sens. -== Sensività del mouse +== Sensibilità Move left == Sinistra Move player to spectators -== Muovi giocatore tra gli spettatori +== Fai osservare il giocatore Move right == Destra @@ -329,13 +332,13 @@ Movement == Movimento Mute when not active -== Silenzioso se inattivo +== Silenzioso quanto inattivo Name == Nome Name plates size -== Lunghezza nomi +== Dimensione nomi Netversion: == Versione net @@ -344,10 +347,10 @@ New name: == Nuovo nome: News -== Notizie +== Novità Next weapon -== Prossima arma +== Arma seguente Nickname == Nickname @@ -362,7 +365,7 @@ No servers found == Nessun server trovato No servers match your filter criteria -== Nessun server rispecchia i tuoi criteri +== Nessun server corrisponde ai tuoi criteri di ricerca Ok == Ok @@ -386,11 +389,17 @@ Pistol == Pistola Play -== Gioca +== Riproduci + +Play background music +== Riproduci musica di sottofondo Player == Giocatore +Player country: +== Filtra per paese: + Player options == Opzioni giocatore @@ -398,22 +407,22 @@ Players == Giocatori Please balance teams! -== Bilancia le squadre! +== Equilibra le squadre! Prev. weapon == Arma precedente Quality Textures -== Qualità Textures +== Texture di qualità Quick search: == Ricerca rapida: Quit -== Esci +== Chiudi Quit anyway? -== Vuoi uscire comunque? +== Vuoi chiudere comunque? REC %3d:%02d == REC %3d:%02d @@ -428,7 +437,7 @@ Red team == Squadra rossa Red team wins! -== La squadra rossa vince! +== La squadra rossa ha vinto! Refresh == Aggiorna @@ -440,13 +449,13 @@ Remote console == Console remota Remove -== Rimuovi +== Elimina Remove friend -== Rimuovi amico +== Elimina amico Rename -== Renomina +== Rinomina Rename demo == Rinomina demo @@ -455,34 +464,34 @@ Reset filter == Azzera filtri Reset to defaults -== Ripristina impostazioni iniziali +== Reimposta Rifle -== Mitra +== Laser Round -== Round +== Turno Sample rate -== Frequenza di campionamento +== Frequenza Sat. -== Sat. +== Saturazione Score -== Punteggi +== Punti Score board -== Tabella dei Punteggi +== Punteggio Score limit -== Punteggio Max. +== Limite punti Scoreboard -== Tabella dei Punteggi +== Punteggi Screenshot -== Schermata +== Cattura schermata Server address: == Indirizzo server: @@ -491,7 +500,7 @@ Server details == Dettagli server Server filter -== Filtri server +== Filtro server Server info == Info server @@ -500,7 +509,7 @@ Server not full == Server non pieno Settings -== Configurazioni +== Opzioni Shotgun == Fucile @@ -509,7 +518,7 @@ Show chat == Mostra chat Show friends only -== Mostra amici +== Mostra solo amici Show ingame HUD == Mostra HUD in gioco @@ -521,43 +530,52 @@ Show only supported == Mostra solo supportati Size: -== Dimensioni: +== Dimensione: Skins -== Skins +== Skin Sound == Suono Sound error -== Suono errore +== Errore suono Sound volume == Volume suono Spectate -== Spettatore +== Osserva + +Spectate next +== Osserva succ. + +Spectate previous +== Osserva prec. Spectator mode -== Modalità spettatore +== Menu osservazione Spectators == Spettatori Standard gametype -== Tipo di gioco standard +== Tipo di gioco normale Standard map -== Mappa standard +== Mappa normale Stop record -== Ferma registrazione +== Ferma reg. + +Strict gametype filter +== Tipo di gioco preciso Sudden Death -== Morte istantanea +== Tempo supplementare Switch weapon on pickup -== Cambia arma automaticamente +== Cambia arma ad ogni raccolta Team == Squadra @@ -566,37 +584,37 @@ Team chat == Chat di squadra Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s e' stato rilasciato! Scaricalo da www.teeworlds.com! +== È uscito Teeworld %s! Scaricalo su www.teeworlds.com! Texture Compression -== Compressione textures +== Compressione texture The audio device couldn't be initialised. == Il dispositivo audio non può essere inizializzato. The server is running a non-standard tuning on a pure game type. -== Il server è attivo con una configurazione non standard in una modalità di gioco pura. +== Il server presenta impostazioni non standard in un tipo di gioco normale. There's an unsaved map in the editor, you might want to save it before you quit the game. -== C'è una mappa non salvata nell'editor, sicuramente vorrai salvarla prima di uscire. +== C'è una mappa non salvata nell'editor, probabilmente vuoi salvarla prima di uscire. Time limit -== Limite tempo. +== Limite di tempo Time limit: %d min -== Limite tempo: %d min +== Limite di tempo: %d min Try again -== Riprova +== Ritenta Type -== Tipologia +== Tipo Type: -== Tipologia: +== Tipo: UI Color -== Colore UI +== Color interfaccia Unable to delete the demo == Impossibile eliminare la demo @@ -608,10 +626,10 @@ Use sounds == Attiva suoni Use team colors for name plates -== Utilizza i colori del team per i nomi +== Usa i colori della squadra nei nomi V-Sync -== V-Sync +== Sincronizzazione verticale Version == Versione @@ -620,7 +638,7 @@ Version: == Versione: Vote command: -== Comando voto: +== Comando di voto: Vote description: == Descrizione voto: @@ -629,10 +647,10 @@ Vote no == Vota no Vote yes -== Vota si +== Vota sì Voting -== Votazione in corso +== Votazione Warmup == Riscaldamento @@ -641,39 +659,24 @@ Weapon == Arma Welcome to Teeworlds -== Benvenuto su Teeworlds! +== Benvenuto su Teeworlds Yes -== Si +== Sì You must restart the game for all settings to take effect. -== E' necessario riavviare il gioco per impostare i cambiamenti. +== Devi riavviare il gioco per rendere effettive le modifiche. Your skin -== Tua skin +== La tua skin no limit == senza limiti ##### needs translation ##### -Demofile: %s -== - -Play background music -== - -Player country: -== - -Spectate next -== - -Spectate previous -== - -Strict gametype filter -== - ##### old translations ##### + +== ## translated strings ##### + diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index a122104e..e3c7c6cb 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes diff --git a/data/languages/serbian.txt b/data/languages/serbian.txt index 693d14ed..e4ec95c2 100644 --- a/data/languages/serbian.txt +++ b/data/languages/serbian.txt @@ -1,14 +1,45 @@ + ##### translated strings ##### +%d Bytes +== %d Bytes + %d of %d servers, %d players == %d od %d server(a), %d igrač(a) +%d%% loaded +== Učitano %d%% + %ds left == Još %ds +%i minute left +== Još %ds + +%i minutes left +== Preostalo: %i min. + +%i second left +== Preostalo: %i min. + +%i seconds left +== Preostalo: %i sek. + +%s wins! +== %s je pobijedio! + +-Page %d- +== -Strana %d- + Abort == Prekini +Add +== Dodaj + +Add Friend +== Dodaj prijatelja + Address == Adresa @@ -21,12 +52,24 @@ Alpha Always show name plates == Uvek prikaži imena igrača +Are you sure that you want to delete the demo? +== Da li sigurni da želite da obrišete demo-snimak? + Are you sure that you want to quit? == Jeste li sigurni da želite da izađete? +Are you sure that you want to remove the player from your friends list? +== Da li ste sigurni da želite da obrišete igrača iz liste prijatelja? + As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. == Pošto prvi put pokrećete igru, molimo da ispod unesete Vaš nadimak (nick). Preporučujemo da proverite podešavanja i podesite ih prema Vašem ukusu pre nego što se konektujete na server. +Automatically record demos +== Automatski snimi demo + +Automatically take game over screenshot +== Automatski napravi screenshot + Blue team == Plavi tim @@ -39,9 +82,18 @@ Body Call vote == Glasanje +Change settings +== Izmeni podešavanja + Chat == Chat +Clan +== Klan + +Client +== Klijent + Close == Zatvori @@ -63,6 +115,18 @@ Console Controls == Kontrole +Count players only +== Izbroj samo igrače + +Country +== Država + +Crc: +== Crc: + +Created: +== Kreirano: + Current == Trenutno @@ -75,6 +139,15 @@ Custom colors Delete == Izbriši +Delete demo +== Obriši demo-snimak + +Demo details +== Detalji demo-a + +Demofile: %s +== Demo-snimak: %s + Demos == Demoi @@ -126,9 +199,18 @@ Filter Fire == Pucanje +Folder +== Direktorijum + Force vote == Obavezno glasanje +Free-View +== Slobodan pregled + +Friends +== Prijatelji + Fullscreen == Čitav ekran @@ -180,6 +262,9 @@ Info Internet == Internet +Invalid Demo +== Neispravan demo-snimak + Join blue == U plavi tim @@ -192,12 +277,18 @@ Join red Jump == Skok +Kick player +== Izbaci igrača iz igre + LAN == LAN Language == Jezik +Length: +== Dužina: + Lht. == Svetl. @@ -210,6 +301,15 @@ MOTD Map == Mapa +Map: +== Mapa: + +Max Screenshots +== Maksimalan broj screenshot-ova + +Max demos +== Maksimalan broj demo-a + Maximum ping: == Maksimalan ping: @@ -222,6 +322,9 @@ Mouse sens. Move left == Nalevo +Move player to spectators +== Prebaci igrača u posmatrače + Move right == Nadesno @@ -234,6 +337,15 @@ Mute when not active Name == Ime +Name plates size +== Veličina pozadine za ime + +Netversion: +== Net-verzija: + +New name: +== Novo ime: + News == Novosti @@ -258,6 +370,12 @@ No servers match your filter criteria Ok == OK +Open +== Otvori + +Parent Folder +== Prethodni direktorijum + Password == Lozinka @@ -273,9 +391,18 @@ Pistol Play == Pokreni +Play background music +== Pozadinska muzika + Player == Igrač +Player country: +== Država + +Player options +== Podešavanja igrača + Players == Igrači @@ -294,6 +421,18 @@ Quick search: Quit == Izlaz +Quit anyway? +== Izlaz? + +REC %3d:%02d +== REC %3d:%02d + +Reason: +== Razlog: + +Record demo +== Snimi demo + Red team == Crveni tim @@ -309,6 +448,18 @@ Refreshing master servers Remote console == Udaljena konzola +Remove +== Ukloni + +Remove friend +== Ukloni prijatelja + +Rename +== Preimenuj + +Rename demo +== Preimenuj demo-snimak + Reset filter == Poništi filter @@ -342,9 +493,15 @@ Scoreboard Screenshot == Screenshot +Server address: +== Adresa servera: + Server details == Podaci o serveru +Server filter +== Filter servera + Server info == O Serveru @@ -360,24 +517,45 @@ Shotgun Show chat == Prikaži chat +Show friends only +== Prikaži isključivo prijatelje + +Show ingame HUD +== Prikaži HUD + Show name plates == Prikaži imena igrača Show only supported == Prikaži samo podržane +Size: +== Veličina: + Skins == Izgled Sound == Zvuk +Sound error +== Problem sa zvukom + Sound volume == Jačina zvuka Spectate == Posmatraj +Spectate next +== Posmatraj narednog + +Spectate previous +== Posmatraj prethodnog + +Spectator mode +== Posmatrački mod + Spectators == Posmatrači @@ -387,6 +565,12 @@ Standard gametype Standard map == Standardna mapa +Stop record +== Prekini snimanje + +Strict gametype filter +== Striktan filter tipa igre + Sudden Death == Iznenadna smrt @@ -405,30 +589,60 @@ Teeworlds %s is out! Download it at www.teeworlds.com! Texture Compression == Kompresija tekstura +The audio device couldn't be initialised. +== Audio-uređaj nije moguće pokrenuti. + The server is running a non-standard tuning on a pure game type. == Server sadrži nestandardna podešavanja. +There's an unsaved map in the editor, you might want to save it before you quit the game. +== Mapa u editoru nije zapamćena, možda želite da je zapamtite pre izlaska iz igre. + Time limit == Max. vremena +Time limit: %d min +== Vremensko ograničenje: %d min. + Try again == Pokušaj ponovo Type == Tip +Type: +== Tip: + UI Color == Boja menija +Unable to delete the demo +== Demo-snimak nije moguće obrisati + +Unable to rename the demo +== Demo-snimak nije moguće preimenovati + Use sounds == Aktiviraj zvuk +Use team colors for name plates +== Koristi timsku boju u prikazu imena + V-Sync == V-Sync Version == Verzija +Version: +== Verzija: + +Vote command: +== Komanda za glasanje: + +Vote description: +== Opis glasanja: + Vote no == Ne @@ -456,223 +670,10 @@ You must restart the game for all settings to take effect. Your skin == Vaš izgled -##### needs translation ##### - -%d Bytes -== %d Bytes - -%d%% loaded -== Učitano %d%% - -%i minute left -== Još %ds - -%i minutes left -== Preostalo: %i min. - -%i second left -== Preostalo: %i min. - -%i seconds left -== Preostalo: %i sek. - -%s wins! -== %s je pobijedio! - --Page %d- -== -Strana %d- - -Add -== Dodaj - -Add Friend -== Dodaj prijatelja - -Are you sure that you want to delete the demo? -== Da li sigurni da želite da obrišete demo-snimak? - -Are you sure that you want to remove the player from your friends list? -== Da li ste sigurni da želite da obrišete igrača iz liste prijatelja? - -Automatically record demos -== Automatski snimi demo - -Automatically take game over screenshot -== Automatski napravi screenshot - -Change settings -== Izmeni podešavanja - -Clan -== Klan - -Client -== Klijent - -Count players only -== Izbroj samo igrače - -Country -== Država - -Crc: -== Crc: - -Created: -== Kreirano: - -Delete demo -== Obriši demo-snimak - -Demo details -== Detalji demo-a - -Demofile: %s -== Demo-snimak: %s - -Folder -== Direktorijum - -Free-View -== Slobodan pregled - -Friends -== Prijatelji - -Invalid Demo -== Neispravan demo-snimak - -Kick player -== Izbaci igrača iz igre - -Length: -== Dužina: - -Map: -== Mapa: - -Max Screenshots -== Maksimalan broj screenshot-ova - -Max demos -== Maksimalan broj demo-a - -Move player to spectators -== Prebaci igrača u posmatrače - -Name plates size -== Veličina pozadine za ime - -Netversion: -== Net-verzija: - -New name: -== Novo ime: - -Open -== Otvori - -Parent Folder -== Prethodni direktorijum - -Play background music -== Pozadinska muzika - -Player country: -== Država - -Player options -== Podešavanja igrača - -Quit anyway? -== Izlaz? - -REC %3d:%02d -== REC %3d:%02d - -Reason: -== Razlog: - -Record demo -== Snimi demo - -Remove -== Ukloni - -Remove friend -== Ukloni prijatelja - -Rename -== Preimenuj - -Rename demo -== Preimenuj demo-snimak - -Server address: -== Adresa servera: - -Server filter -== Filter servera - -Show friends only -== Prikaži isključivo prijatelje - -Show ingame HUD -== Prikaži HUD - -Size: -== Veličina: - -Sound error -== Problem sa zvukom - -Spectate next -== Posmatraj narednog - -Spectate previous -== Posmatraj prethodnog - -Spectator mode -== Posmatrački mod - -Stop record -== Prekini snimanje - -Strict gametype filter -== Striktan filter tipa igre - -The audio device couldn't be initialised. -== Audio-uređaj nije moguće pokrenuti. - -There's an unsaved map in the editor, you might want to save it before you quit the game. -== Mapa u editoru nije zapamćena, možda želite da je zapamtite pre izlaska iz igre. - -Time limit: %d min -== Vremensko ograničenje: %d min. - -Type: -== Tip: - -Unable to delete the demo -== Demo-snimak nije moguće obrisati - -Unable to rename the demo -== Demo-snimak nije moguće preimenovati - -Use team colors for name plates -== Koristi timsku boju u prikazu imena - -Version: -== Verzija: - -Vote command: -== Komanda za glasanje: - -Vote description: -== Opis glasanja: - no limit == bez ograničenja +##### needs translation ##### + ##### old translations ##### -- cgit 1.4.1 From b7bcba7b85fd80d64573f2e9b19ab516a02203fa Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 15 Jul 2011 01:19:13 +0200 Subject: added update for Bulgarian translation by Hip-Hop_Blond --- data/languages/bulgarian.txt | 58 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/data/languages/bulgarian.txt b/data/languages/bulgarian.txt index 80b043a3..38df7891 100644 --- a/data/languages/bulgarian.txt +++ b/data/languages/bulgarian.txt @@ -53,16 +53,16 @@ Always show name plates == Винаги показвай лентите с имената Are you sure that you want to delete the demo? -== Сигурни ли сте че искате да изтриете това демо? +== Сигуен ли си че искаш да изтриеш това демо? Are you sure that you want to quit? -== Сигурни ли сте че искате да напуснете? +== Сигурен ли си че искаш да напуснеш? Are you sure that you want to remove the player from your friends list? -== Сигурни ли сте че искате да премахнете този играч от листа с приятели? +== Сигурен ли си че искаш да премахнеш този играч от листа с приятели? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Тъй като стартирате играта за първи път, моля да въведете вашият ник отдолу. Препоръчително е да проверите и нагласите настройките по ваш избор преди да започнете игра. +== Тъй като стартираш играта за първи път, моля въведи своя ник отдолу. Препоръчително е да провериш и нагласиш настройките по ваш свой избор преди да започнеш игра. Automatically record demos == Записвай демота автоматично @@ -145,6 +145,9 @@ Delete demo Demo details == Детайли за демото +Demofile: %s +== Демофайл: %s + Demos == Демота @@ -347,7 +350,7 @@ News == Новини Next weapon -== Следващо оръжие +== След. оръжие Nickname == Ник @@ -362,7 +365,7 @@ No servers found == Няма намерени сървъри No servers match your filter criteria -== Няма сървъри съответстващи вашите настройки +== Няма сървъри съответстващи твоите настройки Ok == Добре @@ -388,9 +391,15 @@ Pistol Play == Възпроизведи +Play background music +== Пусни музика за фон + Player == Играч +Player country: +== Страна на играча: + Player options == Настройки на Играча @@ -536,7 +545,10 @@ Sound volume == Сила на звука Spectate -== Наблюдавайте +== Наблюдавай + +Spectate next +== Наблюдавай след. Spectator mode == Наблюдател @@ -553,6 +565,9 @@ Standard map Stop record == Спри записа +Strict gametype filter +== Стриктен геймтайп филтър + Sudden Death == Внезапна Смърт @@ -566,13 +581,13 @@ Team chat == Отборен чат Teeworlds %s is out! Download it at www.teeworlds.com! -== Излезна Teeworlds %s! Свалете новата версия от www.teeworlds.com! +== Излезна Teeworlds %s! Свали новата версия от www.teeworlds.com! Texture Compression == Компресиране на Текстурите The audio device couldn't be initialised. -== Аудио устройството не може да бъде стартирано +== Аудио устройството не може да бъде стартирано. The server is running a non-standard tuning on a pure game type. == Този сървър използва нестандартен тунинг на стандартен тип ига. @@ -587,7 +602,7 @@ Time limit: %d min == Лимит на Времето: %d мин Try again -== Опитайте Отново +== Опитай пак Type == Тип @@ -620,10 +635,10 @@ Version: == Версия: Vote command: -== Гласувай за команда: +== Вот команда: Vote description: -== Гласувай за обяснение: +== Вот дефиниция: Vote no == Против @@ -647,33 +662,18 @@ Yes == Да You must restart the game for all settings to take effect. -== Трябва да рестартирате играта за да поемат ефект новите настройки. +== Трябва да рестартираш играта за да поемат ефект новите настройки. Your skin -== Вашият модел +== Твоят модел no limit == Без лимит ##### needs translation ##### -Demofile: %s -== - -Play background music -== - -Player country: -== - -Spectate next -== - Spectate previous == -Strict gametype filter -== - ##### old translations ##### -- cgit 1.4.1 From e55653f1e6cf67494142a0190d3c625d35e27d65 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 15 Jul 2011 01:23:39 +0200 Subject: added update for Spanish translation by GaBOr --- data/languages/spanish.txt | 186 ++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/data/languages/spanish.txt b/data/languages/spanish.txt index 77dc07c7..5348d16a 100644 --- a/data/languages/spanish.txt +++ b/data/languages/spanish.txt @@ -2,7 +2,7 @@ ##### translated strings ##### %d Bytes -== %d Bytes +== %d bytes %d of %d servers, %d players == %d de %d servidores, %d jugadores @@ -11,22 +11,22 @@ == %d%% cargado %ds left -== faltan %ds +== %ds restantes %i minute left -== falta %i minuto +== %i minuto restante %i minutes left -== faltan %i minutos +== %i minutos restantes %i second left -== falta %i segundo +== %i segundo restante %i seconds left -== faltan %i segundos +== %i segundos restantes %s wins! -== %s gana! +== ¡%s gana! -Page %d- == -Página %d- @@ -38,7 +38,7 @@ Add == Añadir Add Friend -== Añadir Amigo +== Añadir amigo Address == Dirección @@ -53,40 +53,40 @@ Always show name plates == Mostrar siempre los apodos Are you sure that you want to delete the demo? -== ¿Seguro que quiere eliminar la demo? +== ¿Estás seguro de que quieres eliminar la demo? Are you sure that you want to quit? -== ¿Seguro que quiere salir? +== ¿Estás seguro de que quieres salir? Are you sure that you want to remove the player from your friends list? -== ¿Estas seguro de que quiere eliminar este jugador de su lista de amigos? +== ¿Estás seguro de que quieres eliminar a este jugador de la lista de amigos? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== Como es la primera vez que abre el juego, por favor, introduzca su apodo. Es recomendable que verifique su configuración y ajuste las preferencias antes de entrar en un servidor. +== Como es la primera vez que abres el juego, por favor, introduce tu apodo. Es recomendable que verifiques tu configuración y ajustes las preferencias antes de unirte a un servidor. Automatically record demos == Grabar demos automáticamente Automatically take game over screenshot -== Pantallazo 'game over' automáticamente +== Captura de pantalla al final de la partida Blue team == Equipo azul Blue team wins! -== Equipo azul gana! +== ¡El equipo azul gana! Body == Cuerpo Call vote -== Votación +== Votar Change settings == Cambiar configuración Chat -== Charla +== Conversación Clan == Clan @@ -107,7 +107,7 @@ Connecting to == Conectando con Connection Problems... -== Problemas de Conexión... +== Problemas de conexión... Console == Consola @@ -119,16 +119,16 @@ Count players only == Solo contar jugadores Country -== Pais +== País Crc: -== Crc: +== CRC: Created: == Creado: Current -== Actualmente +== Actual Current version: %s == Versión actual: %s @@ -143,10 +143,10 @@ Delete demo == Borrar demo Demo details -== Detellades demo +== Detalles de la demo Demofile: %s -== Archivo Demo: %s +== Archivo: %s Demos == Demos @@ -158,13 +158,13 @@ Disconnected == Desconectado Display Modes -== Modos de exibición +== Modos de video Downloading map -== Bajando mapa +== Descargando mapa Draw! -== Empate! +== ¡Empate! Dynamic Camera == Cámara dinámica @@ -179,7 +179,7 @@ Error == Error Error loading demo -== Error al cargar demo +== Error al cargar la demo FSAA samples == Muestras FSAA @@ -206,25 +206,25 @@ Force vote == Forzar Free-View -== Vista Libre +== Vista libre Friends == Amigos Fullscreen -== Pantalla Completa +== Pantalla completa Game == Juego Game info -== Info. sobre el juego +== Información del juego Game over -== Fin del Juego +== Fin de la partida Game type -== Tipo de juego +== Modo Game types: == Tipos de juego: @@ -251,13 +251,13 @@ Hook == Gancho Host address -== Dirección de host +== Dirección del host Hue == Matiz Info -== Info. +== Información Internet == Internet @@ -266,13 +266,13 @@ Invalid Demo == Demo inválida Join blue -== Azul +== Unirse a azul Join game -== Entrar al juego +== Unirse Join red -== Rojo +== Unirse a rojo Jump == Saltar @@ -290,7 +290,7 @@ Length: == Longitud: Lht. -== Luz +== Luminosidad Loading == Cargando @@ -305,10 +305,10 @@ Map: == Mapa: Max Screenshots -== Max Pantallazos +== Número máximo de capturas Max demos -== Max demos +== Número máximo de demos Maximum ping: == Ping máximo: @@ -317,40 +317,40 @@ Miscellaneous == Miscelánea Mouse sens. -== Sens. del ratón +== Sensibilidad ratón Move left -== Izquierda +== Mover a la izquierda Move player to spectators == Mover jugador a espectadores Move right -== Derecha +== Mover a la derecha Movement == Movimiento Mute when not active -== Silenciar en inactivo +== Silenciar si no está activo Name == Nombre Name plates size -== Tamaño de la Fuente (%) +== Tamaño de la fuente de los apodos Netversion: == Versión Net New name: -== Nuevo Nombre: +== Nuevo nombre: News -== Notícia +== Noticias Next weapon -== Próxima arma +== Arma siguiente Nickname == Apodo @@ -365,7 +365,7 @@ No servers found == Ningún servidor encontrado No servers match your filter criteria -== Ningún servidor corresponde a los critérios de filtrado +== Ningún servidor corresponde a los criterios de filtrado Ok == Aceptar @@ -374,7 +374,7 @@ Open == Abrir Parent Folder -== Carpeta superior +== Directorio padre Password == Contraseña @@ -389,7 +389,7 @@ Pistol == Pistola Play -== Asistir +== Reproducir Play background music == Reproducir música de fondo @@ -398,16 +398,16 @@ Player == Jugador Player country: -== Tú Pais +== País del jugador Player options -== Opciones de Jugador +== Opciones de jugador Players == Jugadores Please balance teams! -== Por favor, equilibre los equipos! +== Por favor, ¡equilibrad los equipos! Prev. weapon == Arma anterior @@ -416,7 +416,7 @@ Quality Textures == Texturas de calidad Quick search: -== Busqueda rápida: +== Búsqueda rápida: Quit == Salir @@ -437,7 +437,7 @@ Red team == Equipo rojo Red team wins! -== Ganó el Equipo rojo! +== ¡El equipo rojo gana! Refresh == Actualizar @@ -467,7 +467,7 @@ Reset to defaults == Resetar por defecto Rifle -== Laser +== Láser Round == Ronda @@ -476,40 +476,40 @@ Sample rate == Frecuencia de muestreo Sat. -== Sat. +== Saturación Score == Puntos Score board -== Tabla de puntos +== Puntuación Score limit -== Puntuación Máx. +== Límite puntos Scoreboard == Puntuación Screenshot -== Pantallazo +== Captura de pantalla Server address: -== Dirección d. servidor: +== IP del servidor: Server details -== Detalles del server +== Detalles del servidor Server filter == Filtro del servidor Server info -== Info del server +== Servidor Server not full -== Servidor incompleto +== Servidor sin llenar Settings -== Config. +== Configuración Shotgun == Escopeta @@ -518,16 +518,16 @@ Show chat == Mostrar chat Show friends only -== Mostrar amigos +== Solo mostrar amigos Show ingame HUD -== Mostar HUD en juego +== Mostar HUD durante el juego Show name plates == Mostrar apodos Show only supported -== Mostrar solo soportados +== Mostrar únicamente modos soportados Size: == Tamaño: @@ -545,7 +545,7 @@ Sound volume == Volumen de sonido Spectate -== Observar +== Asistir Spectate next == Observar siguiente @@ -557,55 +557,55 @@ Spectator mode == Modo espectador Spectators -== Observadores +== Espectadores Standard gametype -== Tipo de juego normal +== Tipo de juego estándar Standard map -== Mapa normal +== Mapa estándar Stop record -== Parar grabación +== Detener grabación Strict gametype filter -== Filtro estricto gametype +== Tipo de juego del filtro Sudden Death -== Muerte Súbita +== Muerte súbita Switch weapon on pickup -== Cambiar de arma +== Cambiar al arma recogida Team == Equipo Team chat -== Conv. de equipo +== En equipo Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s ya salió! Descárgalo desde www.teeworlds.com! +== ¡Teeworlds %s ha salido! ¡Descárgalo desde www.teeworlds.com! Texture Compression -== Compresión de Textura +== Compresión de texturas The audio device couldn't be initialised. == El dispositivo de audio no puede ser inicializado. The server is running a non-standard tuning on a pure game type. -== El servidor está ejecutando una afinación no estándar en un tipo de juego puro. +== El servidor está ejecutando una configuración no estándar en un tipo de juego puro. There's an unsaved map in the editor, you might want to save it before you quit the game. -== Tienes un mapa sin guardar en el editor, ¿quiere guardarlo antes de salir? +== Tienes un mapa sin guardar en el editor, quizá quieras guardarlo antes de salir. Time limit -== Tiempo máx. +== Tiempo límite Time limit: %d min -== Tiempo limite: %d min +== Tiempo límite: %d minutos Try again -== Probar de nuevo +== Intentar de nuevo Type == Tipo @@ -614,19 +614,19 @@ Type: == Tipo: UI Color -== Color de menu +== Color de menú Unable to delete the demo -== No se puede eliminar la demo +== No se pudo eliminar la demo Unable to rename the demo -== Imposible renombrar la demo +== No se pudo renombrar la demo Use sounds == Usar sonidos Use team colors for name plates -== Usar el color del equipo en los apodos +== Usar el color de equipo en los apodos V-Sync == V-Sync @@ -638,7 +638,7 @@ Version: == Versión: Vote command: -== Votar comando: +== Comando de votación: Vote description: == Descripción de la votación: @@ -647,10 +647,10 @@ Vote no == Votar no Vote yes -== Votar si +== Votar sí Voting -== Votando +== Votación Warmup == Calentamiento @@ -659,10 +659,10 @@ Weapon == Arma Welcome to Teeworlds -== Bienvenido/a a Teeworlds! +== ¡Bienvenido/a a Teeworlds! Yes -== Si +== Sí You must restart the game for all settings to take effect. == Debes reiniciar el juego para que los cambios tengan efecto. -- cgit 1.4.1 From 737b5540adfbb60afece19155e67285adac87bcb Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 15 Jul 2011 01:27:45 +0200 Subject: added update for Polish translation by Shymwo --- data/languages/polish.txt | 444 +++++++++++++++++++++++----------------------- 1 file changed, 222 insertions(+), 222 deletions(-) diff --git a/data/languages/polish.txt b/data/languages/polish.txt index 6e651e75..25b0b292 100644 --- a/data/languages/polish.txt +++ b/data/languages/polish.txt @@ -1,15 +1,45 @@ ##### translated strings ##### +%d Bytes +== %d Bajtów + %d of %d servers, %d players == %d z %d serwerów, %d graczy +%d%% loaded +== Załadowano %d%% + %ds left -== Jeszcze %d +== Pozostało %ds + +%i minute left +== Pozostała %i minuta + +%i minutes left +== Pozostało %i minut + +%i second left +== Pozostała %i sekunda + +%i seconds left +== Pozostało %i sekund + +%s wins! +== Wygrał %d! + +-Page %d- +== -Strona %d- Abort == Anuluj +Add +== Dodaj + +Add Friend +== Dodaj znajomego + Address == Adres @@ -22,11 +52,23 @@ Alpha Always show name plates == Zawsze pokazuj nicki +Are you sure that you want to delete the demo? +== Czy na pewno chcesz usunąć to demo? + Are you sure that you want to quit? == Czy na pewno chcesz opuścić grę? +Are you sure that you want to remove the player from your friends list? +== Czy na pewno chcesz usunąć tego gracza z listy znajomych? + As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. -== To pierwsze uruchomienie gry, podaj swój nick poniżej. Zalecane jest też sprawdzenie ustawień i dopasowanie ich do siebie przed dołączeniem do gry. +== To pierwsze uruchomienie gry, podaj swój nick poniżej. Zalecane jest też sprawdzenie ustawień i dopasowanie ich do swoich upodobań przed dołączeniem do gry. + +Automatically record demos +== Automatycznie rejestruj dema + +Automatically take game over screenshot +== Automatycznie zrób zrzut ekranu końca gry Blue team == Drużyna niebieskich @@ -40,9 +82,18 @@ Body Call vote == Głosowanie +Change settings +== Zmień ustawienia + Chat == Chat +Clan +== Klan + +Client +== Klient + Close == Zamknij @@ -64,6 +115,18 @@ Console Controls == Sterowanie +Count players only +== Licz tylko graczy + +Country +== Kraj + +Crc: +== Crc: + +Created: +== Utworzony: + Current == Aktualnie @@ -76,6 +139,15 @@ Custom colors Delete == Usuń +Delete demo +== Usuń demo + +Demo details +== Szczegóły dema + +Demofile: %s +== Plik dema: %s + Demos == Dema @@ -107,7 +179,7 @@ Error == Błąd Error loading demo -== Błąd przy ładowaniu demo +== Błąd przy ładowaniu dema FSAA samples == próbki FSAA (anti-aliasing) @@ -127,9 +199,18 @@ Filter Fire == Strzał +Folder +== Katalog + Force vote == Wymuś głosowanie +Free-View +== Wolny widok + +Friends +== Znajomi + Fullscreen == Pełny ekran @@ -181,24 +262,33 @@ Info Internet == Internet +Invalid Demo +== Nieprawidłowe demo + Join blue -== Dołącz do niebieskich +== Do niebieskich Join game == Dołącz Join red -== Dołącz do czerwonych +== Do czerwonych Jump == Skok +Kick player +== Wyrzuć gracza + LAN == LAN Language == Język +Length: +== Długość: + Lht. == Jasn. @@ -211,6 +301,15 @@ MOTD Map == Mapa +Map: +== Mapa: + +Max Screenshots +== Max. screenshotów + +Max demos +== Max. dem + Maximum ping: == Maksymalny ping: @@ -223,6 +322,9 @@ Mouse sens. Move left == Lewo +Move player to spectators +== Przesuń gracza do obserwatorów + Move right == Prawo @@ -233,10 +335,19 @@ Mute when not active == Wycisz kiedy gra nieaktywna Name -== Nick +== Nazwa + +Name plates size +== Wielkość wyświetlanych nicków + +Netversion: +== Wersja sieciowa: + +New name: +== Nowa nazwa: News -== News +== Newsy Next weapon == Następna broń @@ -262,6 +373,9 @@ Ok Open == Otwórz +Parent Folder +== Nadrzędny katalog + Password == Hasło @@ -277,14 +391,23 @@ Pistol Play == Start +Play background music +== Odtwarzaj muzykę w tle + Player == Gracz +Player country: +== Narodowość: + +Player options +== Opcje gracza + Players == Gracze Please balance teams! -== Konieczne wyrównanie drużyn! +== Proszę wyrównać szanse drużyn! Prev. weapon == Poprzednia broń @@ -298,6 +421,18 @@ Quick search: Quit == Wyjście +Quit anyway? +== Wyjść mimo wszystko? + +REC %3d:%02d +== REC %3d:%02d + +Reason: +== Powód: + +Record demo +== Nagraj demo + Red team == Drużyna czerwonych @@ -313,6 +448,18 @@ Refreshing master servers Remote console == Zdalna konsola +Remove +== Usuń + +Remove friend +== Usuń znajomego + +Rename +== Zmień nazwę + +Rename demo +== Zmień nazwę dema + Reset filter == Domyślne filtry @@ -346,11 +493,17 @@ Scoreboard Screenshot == Screenshot +Server address: +== Adres serwera: + Server details == Szczegóły serwera +Server filter +== Filtr serwerów + Server info -== Server info +== Info serwera Server not full == Nie pokazuj pełnych @@ -364,24 +517,45 @@ Shotgun Show chat == Pokaż chat +Show friends only +== Pokaż tylko znajomych + +Show ingame HUD +== Pokaż wewnętrzny HUD + Show name plates == Pokaż nicki Show only supported == Pokaż tylko wspierane +Size: +== Rozmiar: + Skins == Motywy Sound == Dźwięk +Sound error +== Błąd dźwięku + Sound volume == Głośność Spectate == Obserwuj +Spectate next +== Obserwuj następnego + +Spectate previous +== Obserwuj poprzedniego + +Spectator mode +== Tryb obserwatora + Spectators == Obserwatorzy @@ -391,6 +565,12 @@ Standard gametype Standard map == Standardowa mapa +Stop record +== Zatrzymaj nagrywanie + +Strict gametype filter +== Szczegółowy filtr typu gry + Sudden Death == Nagła śmierć @@ -409,30 +589,60 @@ Teeworlds %s is out! Download it at www.teeworlds.com! Texture Compression == Kompresja tekstur +The audio device couldn't be initialised. +== Urządzenie dźwiękowe nie mogło zostać zainicjowane + The server is running a non-standard tuning on a pure game type. == Ten serwer nie korzysta ze standardowych ustawień. +There's an unsaved map in the editor, you might want to save it before you quit the game. +== W edytorze jest niezapisana mapa, być może chcesz ją zapisać przed + Time limit == Limit czasu +Time limit: %d min +== Limit czasowy: %d min + Try again == Ponów próbę Type == Typ +Type: +== Typ: + UI Color == Kolor menu +Unable to delete the demo +== Nie można usunąć dema + +Unable to rename the demo +== Nie można zmienić nazwy dema + Use sounds == Włącz dźwięki +Use team colors for name plates +== Użyj koloru drużyn dla wyświetlania nicków + V-Sync == V-Sync Version == Wersja +Version: +== Wersja: + +Vote command: +== Komenda głosowania: + +Vote description: +== Opis głosowania: + Vote no == Nie @@ -460,220 +670,10 @@ You must restart the game for all settings to take effect. Your skin == Twój wygląd -##### needs translation ##### - -%d Bytes -== - -%d%% loaded -== - -%i minute left -== - -%i minutes left -== - -%i second left -== - -%i seconds left -== - -%s wins! -== - --Page %d- -== - -Add -== - -Add Friend -== - -Are you sure that you want to delete the demo? -== - -Are you sure that you want to remove the player from your friends list? -== - -Automatically record demos -== - -Automatically take game over screenshot -== - -Change settings -== - -Clan -== - -Client -== - -Count players only -== - -Country -== - -Crc: -== - -Created: -== - -Delete demo -== - -Demo details -== - -Demofile: %s -== - -Folder -== - -Free-View -== - -Friends -== - -Invalid Demo -== - -Kick player -== - -Length: -== - -Map: -== - -Max Screenshots -== - -Max demos -== - -Move player to spectators -== - -Name plates size -== - -Netversion: -== - -New name: -== - -Parent Folder -== - -Play background music -== - -Player country: -== - -Player options -== - -Quit anyway? -== - -REC %3d:%02d -== - -Reason: -== - -Record demo -== - -Remove -== - -Remove friend -== - -Rename -== - -Rename demo -== - -Server address: -== - -Server filter -== - -Show friends only -== - -Show ingame HUD -== - -Size: -== - -Sound error -== - -Spectate next -== - -Spectate previous -== - -Spectator mode -== - -Stop record -== - -Strict gametype filter -== - -The audio device couldn't be initialised. -== - -There's an unsaved map in the editor, you might want to save it before you quit the game. -== - -Time limit: %d min -== - -Type: -== - -Unable to delete the demo -== - -Unable to rename the demo -== - -Use team colors for name plates -== - -Version: -== - -Vote command: -== - -Vote description: -== - no limit -== +== bez limitu + +##### needs translation ##### ##### old translations ##### -- cgit 1.4.1 From 05203637028514eb18081d116c9d65a923288236 Mon Sep 17 00:00:00 2001 From: Isadora Date: Sat, 16 Jul 2011 10:11:05 -0700 Subject: Improved the translation of a few strings and corrected unnecessary/wrong changes from last update. --- data/languages/brazilian_portuguese.txt | 206 ++++++++++++++++---------------- 1 file changed, 102 insertions(+), 104 deletions(-) diff --git a/data/languages/brazilian_portuguese.txt b/data/languages/brazilian_portuguese.txt index 6513a31f..68787197 100644 --- a/data/languages/brazilian_portuguese.txt +++ b/data/languages/brazilian_portuguese.txt @@ -1,32 +1,31 @@ - ##### translated strings ##### %d Bytes == %d Bytes %d of %d servers, %d players -== %d de %d Servidores, %d Jogadores +== %d de %d servidores, %d jogadores %d%% loaded -== %d%% Carregado +== %d%% carregado %ds left == Faltam %ds %i minute left -== Falta %i Minuto +== Falta %i minuto %i minutes left -== Faltam %i Minutos +== Faltam %i minutos %i second left -== Falta %i Segundo +== Falta %i segundo %i seconds left -== Faltam %i Segundos +== Faltam %i segundos %s wins! -== %s Vence! +== %s vence! -Page %d- == -Página %d- @@ -38,7 +37,7 @@ Add == Adicionar Add Friend -== Adicionar Amigo +== Adicionar amigo Address == Endereço @@ -53,13 +52,13 @@ Always show name plates == Sempre mostrar apelidos Are you sure that you want to delete the demo? -== Tem certeza que deseja deletar o Demo? +== Tem certeza que deseja deletar o demo? Are you sure that you want to quit? == Você tem certeza que deseja sair? Are you sure that you want to remove the player from your friends list? -== Tem certeza que deseja remover o Jogador de sua Lista de Amigos? +== Tem certeza que deseja remover o jogador de sua lista de amigos? As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. == Como esta é a primeira vez que você abre o jogo, por favor, coloque seu apelido abaixo. É recomendado que você verifique as configurações e então ajuste-as para suas preferências antes de entrar em um servidor. @@ -71,10 +70,10 @@ Automatically take game over screenshot == Capturar tela final de jogo automaticamente Blue team -== Time Azul +== Time azul Blue team wins! -== Vitória do Time Azul! +== Vitória do time azul! Body == Corpo @@ -83,7 +82,7 @@ Call vote == Votar Change settings -== Mudar Configurações +== Mudar configurações Chat == Chat @@ -98,7 +97,7 @@ Close == Fechar Compatible version -== Versão Compatível +== Versão compatível Connect == Conectar @@ -107,7 +106,7 @@ Connecting to == Conectando a Connection Problems... -== Problemas de Conexão... +== Problemas de conexão... Console == Console @@ -116,7 +115,7 @@ Controls == Controles Count players only -== Contar apenas Jogadores +== Contar apenas jogadores Country == País @@ -134,16 +133,16 @@ Current version: %s == Versão atual: %s Custom colors -== Cores Personalizadas +== Cores personalizadas Delete == Deletar Delete demo -== Deletar Demo +== Deletar demo Demo details -== Detalhes do Demo +== Detalhes do demo Demofile: %s == Demo: %s @@ -167,7 +166,7 @@ Draw! == Empate! Dynamic Camera -== Câmera Dinâmica +== Câmera dinâmica Emoticon == Emoticon @@ -179,7 +178,7 @@ Error == Erro Error loading demo -== Erro ao carregar Demo +== Erro ao carregar demo FSAA samples == Amostras FSAA @@ -203,16 +202,16 @@ Folder == Pasta Force vote -== Forçar Votação +== Forçar votação Free-View -== Visualização Livre +== Visualização livre Friends == Amigos Fullscreen -== Tela Cheia +== Tela cheia Game == Jogo @@ -221,13 +220,13 @@ Game info == Jogo Game over -== Fim do Jogo +== Fim do jogo Game type -== Tipo de Jogo +== Tipo de jogo Game types: -== Tipos de Jogo: +== Tipos de jogo: General == Geral @@ -245,13 +244,13 @@ Has people playing == Há pessoas jogando High Detail -== Mostrar Detalhes +== Mostrar detalhes Hook == Gancho Host address -== Endereço do Domínio +== Endereço do servidor Hue == Matiz @@ -263,22 +262,22 @@ Internet == Internet Invalid Demo -== Demo Inválido +== Demo inválido Join blue -== Time Azul +== Azul Join game -== Entrar no Jogo +== Entrar no jogo Join red -== Time Vermelho +== Vermelho Jump == Pular Kick player -== Expulsar Jogador +== Expulsar jogador LAN == LAN @@ -287,10 +286,10 @@ Language == Idioma Length: -== Comprimento: +== Duração: Lht. -== Brilho. +== Luminos. Loading == Carregando @@ -308,37 +307,37 @@ Max Screenshots == Máximo de capturas de tela Max demos -== Máximo de Demos +== Máximo de demos Maximum ping: -== Ping Máximo: +== Ping máximo: Miscellaneous == Diversos Mouse sens. -== Sens. do Mouse +== Sens. do mouse Move left -== Andar para Esquerda +== Esquerda Move player to spectators -== Mover jogador para Espectadores +== Mover jogador para espectadores Move right -== Andar para Direita +== Direita Movement == Movimento Mute when not active -== Silenciar quando Inativo +== Silenciar quando inativo Name == Nome Name plates size -== Tamanho dos Apelidos +== Tamanho dos apelidos Netversion: == Netversion @@ -357,9 +356,9 @@ Nickname No == Não - + No password -== Sem Senha +== Sem senha No servers found == Nenhum servidor encontrado @@ -374,13 +373,13 @@ Open == Abrir Parent Folder -== Diretório Principal +== Diretório pai Password == Senha Password incorrect -== Senha Incorreta +== Senha incorreta Ping == Ping @@ -392,28 +391,28 @@ Play == Assistir Play background music -== Tocar Música de Fundo +== Tocar música de fundo Player == Jogador Player country: -== País do Jogador: +== País do jogador: Player options -== Opções do Jogador +== Opções do jogador Players == Jogadores Please balance teams! -== Favor balancear os Times! +== Favor balancear os times! Prev. weapon == Arma anterior Quality Textures -== Texturas de Qualidade +== Texturas de qualidade Quick search: == Pesquisa rápida: @@ -431,13 +430,13 @@ Reason: == Motivo: Record demo -== Gravar Demo +== Gravar demo Red team -== Time Vermelho +== Time vermelho Red team wins! -== Vitória do Time Vermelho! +== Vitória do time vermelho! Refresh == Atualizar @@ -452,19 +451,19 @@ Remove == Deletar Remove friend -== Deletar Amigo +== Deletar amigo Rename == Renomear Rename demo -== Renomear Demo +== Renomear demo Reset filter -== Resetar Filtro +== Resetar filtro Reset to defaults -== Configurações Padrão +== Resetar configurações Rifle == Laser @@ -473,10 +472,10 @@ Round == Rodada Sample rate -== Frequência do Som +== Frequência do som Sat. -== Saturação. +== Saturação Score == Pontos @@ -485,28 +484,28 @@ Score board == Placar Score limit -== Pontuação Máxima +== Pontuação máx. Scoreboard == Placar Screenshot -== Capturar Tela +== Capturar tela Server address: -== Endereço do Servidor: +== Endereço: Server details -== Detalhes do Servidor +== Detalhes do servidor Server filter -== Filtro de Servidores +== Filtro de servidores Server info == Servidor Server not full -== Servidor Não Lotado +== Servidor não lotado Settings == Configurações @@ -515,19 +514,19 @@ Shotgun == Espingarda Show chat -== Mostrar Chat +== Mostrar chat Show friends only -== Mostrar Apenas Amigos +== Mostrar apenas amigos Show ingame HUD -== Mostrar Display do Jogo +== Mostrar HUD do jogo Show name plates -== Mostrar Apelidos +== Mostrar apelidos Show only supported -== Mostrar apenas o suportado +== Mostrar apenas modos suportados Size: == Tamanho: @@ -539,10 +538,10 @@ Sound == Som Sound error -== Erro de Som +== Erro de som Sound volume -== Volume do Som +== Volume do som Spectate == Observar @@ -554,58 +553,58 @@ Spectate previous == Observar anterior Spectator mode -== Modo Espectador +== Modo espectador Spectators == Espectadores Standard gametype -== Tipo de Jogo Padrão +== Tipo de jogo padrão Standard map -== Mapa Padrão +== Mapa padrão Stop record -== Parar a Gravação +== Parar a gravação Strict gametype filter -== Filtrar tipo Exato de Jogo +== Filtrar tipo de jogo exato Sudden Death == Morte Súbita Switch weapon on pickup -== Mudar arma ao pegá-las +== Equipar arma ao pegá-la Team == Time Team chat -== Chat do Time +== Chat do time Teeworlds %s is out! Download it at www.teeworlds.com! -== Teeworlds %s está pronto! Faça o Download em www.teeworlds.com! +== Teeworlds %s foi lançado! Baixe-o em www.teeworlds.com! Texture Compression -== Compressão da Textura +== Compressão de textura The audio device couldn't be initialised. -== O Dispositivo de áudio não pôde ser inicializado. +== O dispositivo de áudio não pôde ser inicializado. The server is running a non-standard tuning on a pure game type. -== O Servidor está sendo executado com ajustes diferentes de seu Padrão Oficial de tipo de jogo. +== O servidor está rodando com modificações em um tipo de jogo oficial. There's an unsaved map in the editor, you might want to save it before you quit the game. -== Existe um Mapa não salvo no editor, você deve querer salvá-lo antes de sair do jogo. +== Existe um mapa não salvo no editor, você pode querer salvá-lo antes de sair do jogo. Time limit -== Limite de Tempo +== Limite de tempo Time limit: %d min -== Limite de tempo: %d Minutos +== Limite de tempo: %d minutos Try again -== Tente Novamente +== Tente de novo Type == Tipo @@ -614,19 +613,19 @@ Type: == Tipo: UI Color -== Cor do Menu +== Cor do menu Unable to delete the demo -== Não é possível deletar Demo +== Não foi possível deletar o demo Unable to rename the demo -== Não é possível renomear Demo +== Não foi possível renomear o demo Use sounds -== Usar Sons +== Usar sons Use team colors for name plates -== Usar cores dos times em Apelidos +== Usar cores dos times em apelidos V-Sync == V-Sync @@ -638,16 +637,16 @@ Version: == Versão Vote command: -== Comando para Votar: +== Comando da votação: Vote description: -== Descrição da Votação: +== Descrição da votação: Vote no -== Vote Não +== Votar Não Vote yes -== Vote Sim +== Votar Sim Voting == Votação @@ -659,7 +658,7 @@ Weapon == Arma Welcome to Teeworlds -== Bem-Vindo ao Teeworlds! +== Bem-vindo ao Teeworlds! Yes == Sim @@ -668,12 +667,11 @@ You must restart the game for all settings to take effect. == Você deve reiniciar o jogo para que todas as alterações tenham efeito. Your skin -== Sua Skin +== Sua skin no limit -== Sem Limite +== sem limite ##### needs translation ##### ##### old translations ##### - -- cgit 1.4.1 From 6b2dc40570492baf8492d54d513da969c82f4a78 Mon Sep 17 00:00:00 2001 From: Choupom Date: Wed, 20 Jul 2011 10:32:37 +0200 Subject: fixed a rcon authentication issue --- src/engine/server/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 17df19ed..2b174610 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -869,7 +869,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) if(Unpacker.Error() == 0) { - if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0]) + if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0] == 0) { SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password to enable the remote console."); } -- cgit 1.4.1 From 188e6223730e577a1cdfc5891f832c53c23cc146 Mon Sep 17 00:00:00 2001 From: Choupom Date: Mon, 18 Jul 2011 10:34:30 +0200 Subject: fixed auto_map.h header guard --- src/game/editor/auto_map.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/editor/auto_map.h b/src/game/editor/auto_map.h index 4f4cf92e..ee570378 100644 --- a/src/game/editor/auto_map.h +++ b/src/game/editor/auto_map.h @@ -1,5 +1,5 @@ -#ifndef GAME_EDITOR_ED_AUTO_MAP_H -#define GAME_EDITOR_ED_AUTO_MAP_H +#ifndef GAME_EDITOR_AUTO_MAP_H +#define GAME_EDITOR_AUTO_MAP_H #include -- cgit 1.4.1 From c2e8bf5035cbe3f41a71c454e348fc408f17a991 Mon Sep 17 00:00:00 2001 From: Choupom Date: Mon, 18 Jul 2011 10:31:57 +0200 Subject: made a constant for game layer flag --- src/game/editor/io.cpp | 6 +++--- src/game/mapitems.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 9ce6d1f1..768f0fa5 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -295,7 +295,7 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) Item.m_Width = pLayer->m_Width; Item.m_Height = pLayer->m_Height; - Item.m_Flags = pLayer->m_Game; + Item.m_Flags = pLayer->m_Game ? TILESLAYERFLAG_GAME : 0; Item.m_Image = pLayer->m_Image; Item.m_Data = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTile), pLayer->m_pTiles); @@ -516,7 +516,7 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag CMapItemLayerTilemap *pTilemapItem = (CMapItemLayerTilemap *)pLayerItem; CLayerTiles *pTiles = 0; - if(pTilemapItem->m_Flags&1) + if(pTilemapItem->m_Flags&TILESLAYERFLAG_GAME) { pTiles = new CLayerGame(pTilemapItem->m_Width, pTilemapItem->m_Height); MakeGameLayer(pTiles); @@ -537,7 +537,7 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag pGroup->AddLayer(pTiles); void *pData = DataFile.GetData(pTilemapItem->m_Data); pTiles->m_Image = pTilemapItem->m_Image; - pTiles->m_Game = pTilemapItem->m_Flags&1; + pTiles->m_Game = pTilemapItem->m_Flags&TILESLAYERFLAG_GAME; // load layer name if(pTilemapItem->m_Version >= 3) diff --git a/src/game/mapitems.h b/src/game/mapitems.h index 4daf139b..fb66e12d 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -53,6 +53,7 @@ enum TILEFLAG_ROTATE=8, LAYERFLAG_DETAIL=1, + TILESLAYERFLAG_GAME=1, ENTITY_OFFSET=255-16*4, }; -- cgit 1.4.1 From 84e5c534322940a696d9a915829a5e69e5679a28 Mon Sep 17 00:00:00 2001 From: Choupom Date: Mon, 18 Jul 2011 12:05:12 +0200 Subject: added color envelope feature for tilemaps --- src/game/client/components/maplayers.cpp | 6 ++++-- src/game/client/render.h | 5 +++-- src/game/client/render_map.cpp | 18 +++++++++++++++--- src/game/editor/editor.cpp | 20 +++++++++++++++++++- src/game/editor/editor.h | 4 ++++ src/game/editor/io.cpp | 16 ++++++---------- src/game/editor/layer_quads.cpp | 20 +------------------- src/game/editor/layer_tiles.cpp | 13 ++++++++++++- 8 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index b9a2af16..096f9cc5 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -190,9 +190,11 @@ void CMapLayers::OnRender() CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data); Graphics()->BlendNone(); vec4 Color = vec4(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f); - RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); + RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE, + EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset); Graphics()->BlendNormal(); - RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); + RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT, + EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset); } else if(pLayer->m_Type == LAYERTYPE_QUADS) { diff --git a/src/game/client/render.h b/src/game/client/render.h index dc7207be..d3d7fc40 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -39,6 +39,7 @@ enum TILERENDERFLAG_EXTEND=4, }; +typedef void (*ENVELOPE_EVAL)(float TimeOffset, int Env, float *pChannels, void *pUser); class CRenderTools { @@ -70,8 +71,8 @@ public: // map render methods (gc_render_map.cpp) static void RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, float Time, float *pResult); - void RenderQuads(CQuad *pQuads, int NumQuads, int Flags, void (*pfnEval)(float TimeOffset, int Env, float *pChannels, void *pUser), void *pUser); - void RenderTilemap(CTile *pTiles, int w, int h, float Scale, vec4 Color, int Flags); + void RenderQuads(CQuad *pQuads, int NumQuads, int Flags, ENVELOPE_EVAL pfnEval, void *pUser); + void RenderTilemap(CTile *pTiles, int w, int h, float Scale, vec4 Color, int RenderFlags, ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset); // helpers void MapscreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY, diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp index 33cc1c7d..23fa42e0 100644 --- a/src/game/client/render_map.cpp +++ b/src/game/client/render_map.cpp @@ -78,7 +78,7 @@ static void Rotate(CPoint *pCenter, CPoint *pPoint, float Rotation) pPoint->y = (int)(x * sinf(Rotation) + y * cosf(Rotation) + pCenter->y); } -void CRenderTools::RenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, void (*pfnEval)(float TimeOffset, int Env, float *pChannels, void *pUser), void *pUser) +void CRenderTools::RenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, ENVELOPE_EVAL pfnEval, void *pUser) { Graphics()->QuadsBegin(); float Conv = 1/255.0f; @@ -162,7 +162,8 @@ void CRenderTools::RenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, voi Graphics()->QuadsEnd(); } -void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, vec4 Color, int RenderFlags) +void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, vec4 Color, int RenderFlags, + ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset) { //Graphics()->TextureSet(img_get(tmap->image)); float ScreenX0, ScreenY0, ScreenX1, ScreenY1; @@ -174,8 +175,19 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, vec4 float FinalTileSize = Scale/(ScreenX1-ScreenX0) * Graphics()->ScreenWidth(); float FinalTilesetScale = FinalTileSize/TilePixelSize; + float r=1, g=1, b=1, a=1; + if(ColorEnv >= 0) + { + float aChannels[4]; + pfnEval(ColorEnvOffset/1000.0f, ColorEnv, aChannels, pUser); + r = aChannels[0]; + g = aChannels[1]; + b = aChannels[2]; + a = aChannels[3]; + } + Graphics()->QuadsBegin(); - Graphics()->SetColor(Color.r, Color.g, Color.b, Color.a); + Graphics()->SetColor(Color.r*r, Color.g*g, Color.b*b, Color.a*a); int StartY = (int)(ScreenY0/Scale)-1; int StartX = (int)(ScreenX0/Scale)-1; diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index ecb38444..7453472a 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -190,6 +190,24 @@ void CEditorImage::AnalyseTileFlags() } +void CEditor::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser) +{ + CEditor *pThis = (CEditor *)pUser; + if(Env < 0 || Env > pThis->m_Map.m_lEnvelopes.size()) + { + pChannels[0] = 0; + pChannels[1] = 0; + pChannels[2] = 0; + pChannels[3] = 0; + return; + } + + CEnvelope *e = pThis->m_Map.m_lEnvelopes[Env]; + float t = pThis->m_AnimateTime+TimeOffset; + t *= pThis->m_AnimateSpeed; + e->Eval(t, pChannels); +} + /******************************************************** OTHER *********************************************************/ @@ -2086,7 +2104,7 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) m_SelectedGroup = g; static int s_LayerPopupID = 0; if(Result == 2) - UiInvokePopupMenu(&s_LayerPopupID, 0, UI()->MouseX(), UI()->MouseY(), 120, 220, PopupLayer); + UiInvokePopupMenu(&s_LayerPopupID, 0, UI()->MouseX(), UI()->MouseY(), 120, 245, PopupLayer); } LayerCur += 14.0f; diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index d282f5e1..1a904953 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -406,6 +406,8 @@ public: int m_Width; int m_Height; CColor m_Color; + int m_ColorEnv; + int m_ColorEnvOffset; CTile *m_pTiles; }; @@ -663,6 +665,8 @@ public: CEditorMap m_Map; + static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser); + void DoMapBorder(); int DoButton_Editor_Common(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_Editor(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 768f0fa5..68330f03 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -286,12 +286,9 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) Item.m_Layer.m_Flags = pLayer->m_Flags; Item.m_Layer.m_Type = pLayer->m_Type; - Item.m_Color.r = pLayer->m_Color.r; - Item.m_Color.g = pLayer->m_Color.g; - Item.m_Color.b = pLayer->m_Color.b; - Item.m_Color.a = pLayer->m_Color.a; - Item.m_ColorEnv = -1; // not in use right now - Item.m_ColorEnvOffset = 0; + Item.m_Color = pLayer->m_Color; + Item.m_ColorEnv = pLayer->m_ColorEnv; + Item.m_ColorEnvOffset = pLayer->m_ColorEnvOffset; Item.m_Width = pLayer->m_Width; Item.m_Height = pLayer->m_Height; @@ -526,10 +523,9 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag { pTiles = new CLayerTiles(pTilemapItem->m_Width, pTilemapItem->m_Height); pTiles->m_pEditor = m_pEditor; - pTiles->m_Color.r = pTilemapItem->m_Color.r; - pTiles->m_Color.g = pTilemapItem->m_Color.g; - pTiles->m_Color.b = pTilemapItem->m_Color.b; - pTiles->m_Color.a = pTilemapItem->m_Color.a; + pTiles->m_Color = pTilemapItem->m_Color; + pTiles->m_ColorEnv = pTilemapItem->m_ColorEnv; + pTiles->m_ColorEnvOffset = pTilemapItem->m_ColorEnvOffset; } pLayer = pTiles; diff --git a/src/game/editor/layer_quads.cpp b/src/game/editor/layer_quads.cpp index a0c0d544..d0b66405 100644 --- a/src/game/editor/layer_quads.cpp +++ b/src/game/editor/layer_quads.cpp @@ -21,31 +21,13 @@ CLayerQuads::~CLayerQuads() { } -static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser) -{ - CEditor *pEditor = (CEditor *)pUser; - if(Env < 0 || Env > pEditor->m_Map.m_lEnvelopes.size()) - { - pChannels[0] = 0; - pChannels[1] = 0; - pChannels[2] = 0; - pChannels[3] = 0; - return; - } - - CEnvelope *e = pEditor->m_Map.m_lEnvelopes[Env]; - float t = pEditor->m_AnimateTime+TimeOffset; - t *= pEditor->m_AnimateSpeed; - e->Eval(t, pChannels); -} - void CLayerQuads::Render() { Graphics()->TextureSet(-1); if(m_Image >= 0 && m_Image < m_pEditor->m_Map.m_lImages.size()) Graphics()->TextureSet(m_pEditor->m_Map.m_lImages[m_Image]->m_TexID); - m_pEditor->RenderTools()->RenderQuads(m_lQuads.base_ptr(), m_lQuads.size(), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT, EnvelopeEval, m_pEditor); + m_pEditor->RenderTools()->RenderQuads(m_lQuads.base_ptr(), m_lQuads.size(), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT, m_pEditor->EnvelopeEval, m_pEditor); } CQuad *CLayerQuads::NewQuad() diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index ebaa640a..5662613c 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -25,6 +25,8 @@ CLayerTiles::CLayerTiles(int w, int h) m_Color.g = 255; m_Color.b = 255; m_Color.a = 255; + m_ColorEnv = -1; + m_ColorEnvOffset = 0; m_pTiles = new CTile[m_Width*m_Height]; mem_zero(m_pTiles, m_Width*m_Height*sizeof(CTile)); @@ -62,7 +64,8 @@ void CLayerTiles::Render() m_TexID = m_pEditor->m_Map.m_lImages[m_Image]->m_TexID; Graphics()->TextureSet(m_TexID); vec4 Color = vec4(m_Color.r/255.0f, m_Color.g/255.0f, m_Color.b/255.0f, m_Color.a/255.0f); - m_pEditor->RenderTools()->RenderTilemap(m_pTiles, m_Width, m_Height, 32.0f, Color, LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT); + m_pEditor->RenderTools()->RenderTilemap(m_pTiles, m_Width, m_Height, 32.0f, Color, LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT, + m_pEditor->EnvelopeEval, m_pEditor, m_ColorEnv, m_ColorEnvOffset); } int CLayerTiles::ConvertX(float x) const { return (int)(x/32.0f); } @@ -412,6 +415,8 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) PROP_SHIFT, PROP_IMAGE, PROP_COLOR, + PROP_COLOR_ENV, + PROP_COLOR_ENV_OFFSET, NUM_PROPS, }; @@ -427,6 +432,8 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) {"Shift", 0, PROPTYPE_SHIFT, 0, 0}, {"Image", m_Image, PROPTYPE_IMAGE, 0, 0}, {"Color", Color, PROPTYPE_COLOR, 0, 0}, + {"Color Env", m_ColorEnv+1, PROPTYPE_INT_STEP, 0, m_pEditor->m_Map.m_lEnvelopes.size()+1}, + {"Color TO", m_ColorEnvOffset, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {0}, }; @@ -465,6 +472,10 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) m_Color.b = (NewVal>>8)&0xff; m_Color.a = NewVal&0xff; } + if(Prop == PROP_COLOR_ENV) + m_ColorEnv = clamp(NewVal-1, -1, m_pEditor->m_Map.m_lEnvelopes.size()-1); + if(Prop == PROP_COLOR_ENV_OFFSET) + m_ColorEnvOffset = NewVal; return 0; } -- cgit 1.4.1 From 6312a2d71ca35cd925602bf978ef7c9483d6f78f Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 20 Jul 2011 22:18:31 +0200 Subject: fixed few things in th editor --- src/game/editor/editor.cpp | 2 +- src/game/editor/popups.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 7453472a..500e600b 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -193,7 +193,7 @@ void CEditorImage::AnalyseTileFlags() void CEditor::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser) { CEditor *pThis = (CEditor *)pUser; - if(Env < 0 || Env > pThis->m_Map.m_lEnvelopes.size()) + if(Env < 0 || Env >= pThis->m_Map.m_lEnvelopes.size()) { pChannels[0] = 0; pChannels[1] = 0; diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index d8b8a91e..f29ae7e2 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -177,7 +177,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View) static float s_Name = 0; pEditor->UI()->DoLabel(&Button, "Name:", 10.0f, -1, -1); Button.VSplitLeft(40.0f, 0, &Button); - pEditor->DoEditBox(&s_Name, &Button, pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_aName, sizeof(pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_aName), 10.0f, &s_Name); + if(pEditor->DoEditBox(&s_Name, &Button, pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_aName, sizeof(pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_aName), 10.0f, &s_Name)) + pEditor->m_Map.m_Modified = true; } enum @@ -264,7 +265,8 @@ int CEditor::PopupLayer(CEditor *pEditor, CUIRect View) static float s_Name = 0; pEditor->UI()->DoLabel(&Button, "Name:", 10.0f, -1, -1); Button.VSplitLeft(40.0f, 0, &Button); - pEditor->DoEditBox(&s_Name, &Button, pEditor->GetSelectedLayer(0)->m_aName, sizeof(pEditor->GetSelectedLayer(0)->m_aName), 10.0f, &s_Name); + if(pEditor->DoEditBox(&s_Name, &Button, pEditor->GetSelectedLayer(0)->m_aName, sizeof(pEditor->GetSelectedLayer(0)->m_aName), 10.0f, &s_Name)) + pEditor->m_Map.m_Modified = true; } View.HSplitBottom(10.0f, &View, 0); -- cgit 1.4.1 From a3613605c35326a0c9abceef6f6e0f4bb565c60e Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 21 Jul 2011 18:54:53 +0200 Subject: added update for Polish translation by Shymwo --- data/languages/brazilian_portuguese.txt | 4 +- data/languages/polish.txt | 73 +++++++++++++++++---------------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/data/languages/brazilian_portuguese.txt b/data/languages/brazilian_portuguese.txt index 68787197..a83a0d05 100644 --- a/data/languages/brazilian_portuguese.txt +++ b/data/languages/brazilian_portuguese.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d Bytes @@ -356,7 +357,7 @@ Nickname No == Não - + No password == Sem senha @@ -675,3 +676,4 @@ no limit ##### needs translation ##### ##### old translations ##### + diff --git a/data/languages/polish.txt b/data/languages/polish.txt index 25b0b292..e955e1e6 100644 --- a/data/languages/polish.txt +++ b/data/languages/polish.txt @@ -14,16 +14,16 @@ == Pozostało %ds %i minute left -== Pozostała %i minuta +== Pozostało minut: %i %i minutes left -== Pozostało %i minut +== Pozostało minut: %i %i second left -== Pozostała %i sekunda +== Pozostało sekund: %i %i seconds left -== Pozostało %i sekund +== Pozostało sekund: %i %s wins! == Wygrał %d! @@ -50,7 +50,7 @@ Alpha == Alfa Always show name plates -== Zawsze pokazuj nicki +== Zawsze pokazuj nicki graczy Are you sure that you want to delete the demo? == Czy na pewno chcesz usunąć to demo? @@ -71,10 +71,10 @@ Automatically take game over screenshot == Automatycznie zrób zrzut ekranu końca gry Blue team -== Drużyna niebieskich +== Niebiescy Blue team wins! -== Drużyna niebieskich wygrała! +== Niebiescy wygrali! Body == Ciało @@ -125,7 +125,7 @@ Crc: == Crc: Created: -== Utworzony: +== Utworzono: Current == Aktualnie @@ -134,7 +134,7 @@ Current version: %s == Aktualna wersja: %s Custom colors -== Własne kolory +== Dostosuj kolory Delete == Usuń @@ -170,7 +170,7 @@ Dynamic Camera == Dynamiczna kamera Emoticon -== Emotikonka +== Emotikona Enter == Wejdź @@ -182,7 +182,7 @@ Error loading demo == Błąd przy ładowaniu dema FSAA samples -== próbki FSAA (anti-aliasing) +== Próbkowanie FSAA (Antyaliasing) Favorite == Ulubiony @@ -206,7 +206,7 @@ Force vote == Wymuś głosowanie Free-View -== Wolny widok +== Wolna kamera Friends == Znajomi @@ -218,7 +218,7 @@ Game == Gra Game info -== Informacje o grze +== Info o grze Game over == Koniec gry @@ -245,7 +245,7 @@ Has people playing == Nie pokazuj pustych High Detail -== Wysoka jakość obrazu +== Wysoka jakość Hook == Hak @@ -290,7 +290,7 @@ Length: == Długość: Lht. -== Jasn. +== Jasność Loading == Ładowanie @@ -305,10 +305,10 @@ Map: == Mapa: Max Screenshots -== Max. screenshotów +== Maksymalnie screenshotów Max demos -== Max. dem +== Maksymalnie dem Maximum ping: == Maksymalny ping: @@ -320,19 +320,19 @@ Mouse sens. == Czułość myszy Move left -== Lewo +== W lewo Move player to spectators == Przesuń gracza do obserwatorów Move right -== Prawo +== W prawo Movement == Ruch Mute when not active -== Wycisz kiedy gra nieaktywna +== Wycisz, kiedy gra nieaktywna Name == Nazwa @@ -347,7 +347,7 @@ New name: == Nowa nazwa: News -== Newsy +== Wiadomości Next weapon == Następna broń @@ -368,7 +368,7 @@ No servers match your filter criteria == Nie znaleziono serwerów spełniających twoje kryteria Ok -== OK +== Ok Open == Otwórz @@ -389,7 +389,7 @@ Pistol == Pistolet Play -== Start +== Graj Play background music == Odtwarzaj muzykę w tle @@ -434,10 +434,10 @@ Record demo == Nagraj demo Red team -== Drużyna czerwonych +== Czerwoni Red team wins! -== Drużyna czerwonych wygrała! +== Czerwoni wygrali! Refresh == Odśwież @@ -473,10 +473,10 @@ Round == Runda Sample rate -== Próbkowanie +== Częstotliwość próbkowania Sat. -== Nasyc. +== Nasycenie Score == Wynik @@ -566,7 +566,7 @@ Standard map == Standardowa mapa Stop record -== Zatrzymaj nagrywanie +== Zakończ REC Strict gametype filter == Szczegółowy filtr typu gry @@ -584,7 +584,7 @@ Team chat == Chat drużynowy Teeworlds %s is out! Download it at www.teeworlds.com! -== Wydano Teeworlds %s! Ściągnij je z www.teeworlds.com! +== Nowa wersja Teeworlds %s jest dostępna! Do ściągnięcia z www.teeworlds.com! Texture Compression == Kompresja tekstur @@ -593,16 +593,16 @@ The audio device couldn't be initialised. == Urządzenie dźwiękowe nie mogło zostać zainicjowane The server is running a non-standard tuning on a pure game type. -== Ten serwer nie korzysta ze standardowych ustawień. +== Ten serwer korzysta z niestandardowych ustawień. There's an unsaved map in the editor, you might want to save it before you quit the game. -== W edytorze jest niezapisana mapa, być może chcesz ją zapisać przed +== W edytorze jest niezapisana mapa! Zapisz ją, jeśli nie chcesz Time limit == Limit czasu Time limit: %d min -== Limit czasowy: %d min +== Limit czasu: %d min Try again == Ponów próbę @@ -629,7 +629,7 @@ Use team colors for name plates == Użyj koloru drużyn dla wyświetlania nicków V-Sync -== V-Sync +== Synchronizacja pionowa (V-Sync) Version == Wersja @@ -638,7 +638,7 @@ Version: == Wersja: Vote command: -== Komenda głosowania: +== Polecenie głosowania: Vote description: == Opis głosowania: @@ -665,7 +665,7 @@ Yes == Tak You must restart the game for all settings to take effect. -== Gra musi zostać uruchomiona ponownie, żeby nowe ustawienia weszły w życie. +== Uruchom ponownie grę, aby użyć nowych ustawieńn Your skin == Twój wygląd @@ -677,3 +677,6 @@ no limit ##### old translations ##### +utracić swojej pracy! +== + -- cgit 1.4.1 From b7aa8af7aada959f3cb1d57df4a7d8d83965c4ad Mon Sep 17 00:00:00 2001 From: Choupom Date: Sat, 23 Jul 2011 12:03:15 +0200 Subject: thats why magic values sux --- src/game/server/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 3e4d7be5..38baad75 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -61,7 +61,7 @@ void CPlayer::Tick() } if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW) - m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -5000.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f)); + m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -500.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f)); if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick()) m_Spawning = true; -- cgit 1.4.1 From f5fff81abb6766dc583701f3673b9ebece28856d Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 23 Jul 2011 19:54:49 +0200 Subject: linked the runtime library statically within sdl. Closes #797 --- other/sdl/vc2005libs/SDL.dll | Bin 243712 -> 343552 bytes other/sdl/vc2005libs/SDL.lib | Bin 42698 -> 42698 bytes other/sdl/vc2005libs/SDLmain.lib | Bin 24330 -> 22852 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/other/sdl/vc2005libs/SDL.dll b/other/sdl/vc2005libs/SDL.dll index 9663f9b0..429ae545 100644 Binary files a/other/sdl/vc2005libs/SDL.dll and b/other/sdl/vc2005libs/SDL.dll differ diff --git a/other/sdl/vc2005libs/SDL.lib b/other/sdl/vc2005libs/SDL.lib index e2d84a0a..f4e860f8 100644 Binary files a/other/sdl/vc2005libs/SDL.lib and b/other/sdl/vc2005libs/SDL.lib differ diff --git a/other/sdl/vc2005libs/SDLmain.lib b/other/sdl/vc2005libs/SDLmain.lib index 6cc1c5a8..825c03b9 100644 Binary files a/other/sdl/vc2005libs/SDLmain.lib and b/other/sdl/vc2005libs/SDLmain.lib differ -- cgit 1.4.1 From 65d312fd06ef7730cb6699923e17d8b05bd764d0 Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 28 Jul 2011 22:01:14 +0200 Subject: fixed problem with lineinput. Closes #802 --- src/game/client/lineinput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/client/lineinput.cpp b/src/game/client/lineinput.cpp index 29b891c2..2de85d66 100644 --- a/src/game/client/lineinput.cpp +++ b/src/game/client/lineinput.cpp @@ -42,7 +42,7 @@ bool CLineInput::Manipulate(IInput::CEvent e, char *pStr, int StrMaxSize, int *p if (Len < StrMaxSize - CharSize && CursorPos < StrMaxSize - CharSize) { - mem_move(pStr + CursorPos + CharSize, pStr + CursorPos, Len - CursorPos + CharSize); + mem_move(pStr + CursorPos + CharSize, pStr + CursorPos, Len-CursorPos+1); // +1 == null term for(int i = 0; i < CharSize; i++) pStr[CursorPos+i] = Tmp[i]; CursorPos += CharSize; -- cgit 1.4.1 From 2ba6fbd7314bfce9cedf93e6f2b1e7f8b5ac7a84 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Sat, 2 Jul 2011 08:36:14 +0200 Subject: added econ functionality --- src/engine/server/econ.cpp | 0 src/engine/server/econ.h | 0 src/engine/server/server.cpp | 116 ++++++++++++++++++- src/engine/server/server.h | 25 +++- src/engine/shared/config_variables.h | 4 + src/engine/shared/network.h | 78 +++++++++++++ src/engine/shared/network_console.cpp | 144 +++++++++++++++++++++++ src/engine/shared/network_console_conn.cpp | 176 +++++++++++++++++++++++++++++ 8 files changed, 539 insertions(+), 4 deletions(-) create mode 100644 src/engine/server/econ.cpp create mode 100644 src/engine/server/econ.h create mode 100644 src/engine/shared/network_console.cpp create mode 100644 src/engine/shared/network_console_conn.cpp diff --git a/src/engine/server/econ.cpp b/src/engine/server/econ.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/engine/server/econ.h b/src/engine/server/econ.h new file mode 100644 index 00000000..e69de29b diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 2b174610..8e151035 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -317,8 +317,15 @@ int CServer::Init() m_aClients[i].m_Snapshots.Init(); } + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + m_aEconClients[i].m_State = CEconClient::STATE_EMPTY; + } + m_CurrentGameTick = 0; + m_UseEcon = 0; + return 0; } @@ -611,6 +618,30 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) return 0; } +int CServer::NewConsoleClientCallback(int EconID, void *pUser) +{ + CServer *pThis = (CServer *)pUser; + pThis->m_aEconClients[EconID].m_State = CEconClient::STATE_CONNECTED; + pThis->m_NetConsole.SetTimeout(EconID, g_Config.m_SvEconAuthTimeout); + return 0; +} + +int CServer::DelConsoleClientCallback(int EconID, const char *pReason, void *pUser) +{ + CServer *pThis = (CServer *)pUser; + + NETADDR Addr = pThis->m_NetConsole.ClientAddr(EconID); + char aAddrStr[NETADDR_MAXSTRSIZE]; + net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "econ client dropped. eid=%d addr=%s reason='%s'", EconID, aAddrStr, pReason); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); + + pThis->m_aEconClients[EconID].m_State = CEconClient::STATE_EMPTY; + return 0; +} + + void CServer::SendMap(int ClientID) { CMsgPacker Msg(NETMSG_MAP_CHANGE); @@ -633,7 +664,12 @@ void CServer::SendRconLine(int ClientID, const char *pLine) SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); } -void CServer::SendRconLineAuthed(const char *pLine, void *pUser) +void CServer::SendEconLine(int EconID, const char *pLine) +{ + m_NetConsole.Send(EconID, pLine); +} + +void CServer::SendConsoleLineAuthed(const char *pLine, void *pUser) { CServer *pThis = (CServer *)pUser; static volatile int ReentryGuard = 0; @@ -648,6 +684,15 @@ void CServer::SendRconLineAuthed(const char *pLine, void *pUser) pThis->SendRconLine(i, pLine); } + if(pThis->m_UseEcon) + { + for(i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + if(pThis->m_aEconClients[i].m_State == CEconClient::STATE_AUTHED) + pThis->SendEconLine(i, pLine); + } + } + ReentryGuard--; } @@ -1084,6 +1129,47 @@ void CServer::PumpNetwork() else ProcessClientPacket(&Packet); } + + if(m_UseEcon) + EconPumpNetwork(); +} + +void CServer::EconPumpNetwork() +{ + m_NetConsole.Update(); + + char aBuf[NET_MAX_PACKETSIZE]; + int EconID; + + while(m_NetConsole.Recv(aBuf, sizeof(aBuf) - 1, &EconID)) + { + dbg_assert(m_aEconClients[EconID].m_State != CEconClient::STATE_EMPTY, "got message from empty slot"); + if(m_aEconClients[EconID].m_State == CEconClient::STATE_CONNECTED) + { + if(str_comp(aBuf, g_Config.m_SvRconPassword) == 0) + { + m_aEconClients[EconID].m_State = CEconClient::STATE_AUTHED; + m_NetConsole.Send(EconID, "Authentication successful. Remote console access granted."); + m_NetConsole.SetTimeout(EconID, g_Config.m_SvEconTimeout); + + str_format(aBuf, sizeof(aBuf), "EconID=%d authed", EconID); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + } + else + { + m_NetConsole.Send(EconID, "Wrong password"); + } + } + else if(m_aEconClients[EconID].m_State == CEconClient::STATE_AUTHED) + { + char aFormatted[256]; + str_format(aFormatted, sizeof(aBuf), "eid=%d cmd='%s'", EconID, aBuf); + Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aFormatted); + m_RconClientID = EconID; + Console()->ExecuteLine(aBuf); + m_RconClientID = -1; + } + } } char *CServer::GetMapName() @@ -1158,7 +1244,7 @@ int CServer::Run() m_pStorage = Kernel()->RequestInterface(); // - Console()->RegisterPrintCallback(SendRconLineAuthed, this); + Console()->RegisterPrintCallback(SendConsoleLineAuthed, this); // load map if(!LoadMap(g_Config.m_SvMap)) @@ -1181,7 +1267,6 @@ int CServer::Run() BindAddr.port = g_Config.m_SvPort; } - if(!m_NetServer.Open(BindAddr, g_Config.m_SvMaxClients, g_Config.m_SvMaxClientsPerIP, 0)) { dbg_msg("server", "couldn't open socket. port might already be in use"); @@ -1190,6 +1275,31 @@ int CServer::Run() m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this); + if(g_Config.m_SvEconPort && g_Config.m_SvRconPassword[0]) + { + dbg_msg("econ", "binding econ to %s:%d", g_Config.m_SvEconBindaddr, g_Config.m_SvEconPort); + if(g_Config.m_SvEconBindaddr[0] && net_host_lookup(g_Config.m_SvEconBindaddr, &BindAddr, NETTYPE_ALL) == 0) + { + BindAddr.port = g_Config.m_SvEconPort; + } + else + { + mem_zero(&BindAddr, sizeof(BindAddr)); + BindAddr.type = NETTYPE_ALL; + BindAddr.port = g_Config.m_SvEconPort; + } + + if(m_NetConsole.Open(BindAddr, 0)) + { + m_NetConsole.SetCallbacks(NewConsoleClientCallback, DelConsoleClientCallback, this); + m_UseEcon = 1; + } + else + { + dbg_msg("econ", "couldn't open econ socket. port might already be in use"); + } + } + char aBuf[256]; str_format(aBuf, sizeof(aBuf), "server name is '%s'", g_Config.m_SvName); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 5b6e038d..d744b9ff 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -109,10 +109,26 @@ public: CClient m_aClients[MAX_CLIENTS]; + class CEconClient + { + public: + enum + { + STATE_EMPTY=0, + STATE_CONNECTED, + STATE_AUTHED + }; + + int m_State; + }; + + CEconClient m_aEconClients[NET_MAX_CONSOLE_CLIENTS]; + CSnapshotDelta m_SnapshotDelta; CSnapshotBuilder m_SnapshotBuilder; CSnapIDPool m_IDPool; CNetServer m_NetServer; + CNetConsole m_NetConsole; IEngineMap *m_pMap; @@ -123,6 +139,8 @@ public: int m_RconClientID; int m_RconAuthLevel; + int m_UseEcon; + int64 m_Lastheartbeat; //static NETADDR4 master_server; @@ -168,10 +186,14 @@ public: static int NewClientCallback(int ClientID, void *pUser); static int DelClientCallback(int ClientID, const char *pReason, void *pUser); + static int NewConsoleClientCallback(int EconID, void *pUser); + static int DelConsoleClientCallback(int EconID, const char *pReason, void *pUser); + void SendMap(int ClientID); void SendConnectionReady(int ClientID); void SendRconLine(int ClientID, const char *pLine); - static void SendRconLineAuthed(const char *pLine, void *pUser); + void SendEconLine(int EconID, const char *pLine); + static void SendConsoleLineAuthed(const char *pLine, void *pUser); void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID); void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID); @@ -185,6 +207,7 @@ public: int BanAdd(NETADDR Addr, int Seconds, const char *pReason); int BanRemove(NETADDR Addr); + void EconPumpNetwork(); void PumpNetwork(); diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 213ebf26..fd318a7d 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -86,6 +86,10 @@ MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remo MACRO_CONFIG_STR(SvRconModPassword, sv_rcon_mod_password, 32, "", CFGFLAG_SERVER, "Remote console password for moderators (limited access)") MACRO_CONFIG_INT(SvRconMaxTries, sv_rcon_max_tries, 3, 0, 100, CFGFLAG_SERVER, "Maximum number of tries for remote console authentication") MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if remote console authentication fails. 0 makes it just use kick") +MACRO_CONFIG_STR(SvEconBindaddr, sv_econ_bindaddr, 128, "localhost", CFGFLAG_SERVER, "Address to bind the external console to. Anything but 'localhost' is dangerous") +MACRO_CONFIG_INT(SvEconPort, sv_econ_port, 0, 0, 0, CFGFLAG_SERVER, "Port to use for the external console") +MACRO_CONFIG_INT(SvEconAuthTimeout, sv_econ_auth_timeout, 30, 1, 120, CFGFLAG_SERVER, "Time in seconds before the the econ authentification times out") +MACRO_CONFIG_INT(SvEconTimeout, sv_econ_timeout, 300, 1, 3600, CFGFLAG_SERVER, "Time in seconds before the econ connection times out") 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/network.h b/src/engine/shared/network.h index 228ba6dd..d0b78d05 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -49,6 +49,7 @@ enum NET_MAX_CHUNKHEADERSIZE = 5, NET_PACKETHEADERSIZE = 3, NET_MAX_CLIENTS = 16, + NET_MAX_CONSOLE_CLIENTS = 16, NET_MAX_SEQUENCE = 1<<10, NET_SEQUENCE_MASK = NET_MAX_SEQUENCE-1, @@ -192,6 +193,41 @@ public: int AckSequence() const { return m_Ack; } }; +class CConsoleNetConnection +{ +private: + unsigned m_State; + + NETADDR m_PeerAddr; + NETSOCKET m_Socket; + + char m_aBuffer[NET_MAX_PACKETSIZE]; + char *m_pBufferPos; + + char m_aErrorString[256]; + + int m_Timeout; + int64 m_LastRecvTime; + +public: + void Init(NETSOCKET Socket); + void Init(NETSOCKET Socket, const NETADDR *pAddr); + int Connect(const NETADDR *pAddr); + void Disconnect(const char *pReason); + + int State() const { return m_State; } + NETADDR PeerAddress() const { return m_PeerAddr; } + const char *ErrorString() const { return m_aErrorString; } + + void SetTimeout(int Timeout) { m_Timeout = Timeout; } + int Timeout() const { return m_Timeout; } + + void Reset(); + int Update(); + int Send(const char *pLine); + int Recv(char *pLine, int MaxLength); +}; + class CNetRecvUnpacker { public: @@ -292,6 +328,48 @@ public: void SetMaxClientsPerIP(int Max); }; +class CNetConsole +{ +private: + struct CSlot + { + CConsoleNetConnection m_Connection; + }; + + NETSOCKET m_Socket; + CSlot m_aSlots[NET_MAX_CLIENTS]; + + NETFUNC_NEWCLIENT m_pfnNewClient; + NETFUNC_DELCLIENT m_pfnDelClient; + void *m_UserPtr; + + CNetRecvUnpacker m_RecvUnpacker; + +public: + int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); + + // + bool Open(NETADDR BindAddr, int Flags); + int Close(); + + // + int Broadcast(const char *pLine); + int Recv(char *pLine, int MaxLength, int *pClientID = 0); + int Send(int ClientID, const char *pLine); + int Update(); + + // + int AcceptClient(NETSOCKET Socket, const NETADDR *pAddr); + int Drop(int ClientID, const char *pReason); + + // + void SetTimeout(int ClientID, int Timeout) { m_aSlots[ClientID].m_Connection.SetTimeout(Timeout); } + + // status requests + int Timeout(int ClientID) { return m_aSlots[ClientID].m_Connection.Timeout(); } + NETADDR ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } +}; + // client side diff --git a/src/engine/shared/network_console.cpp b/src/engine/shared/network_console.cpp new file mode 100644 index 00000000..3e50a1ac --- /dev/null +++ b/src/engine/shared/network_console.cpp @@ -0,0 +1,144 @@ +/* (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" + +bool CNetConsole::Open(NETADDR BindAddr, int Flags) +{ + // zero out the whole structure + mem_zero(this, sizeof(*this)); + + // open socket + m_Socket = net_tcp_create(&BindAddr); + if(!m_Socket.type) + return false; + if(net_tcp_listen(m_Socket, NET_MAX_CONSOLE_CLIENTS)) + return false; + net_tcp_set_non_blocking(m_Socket); + + for(int i = 0; i < NET_MAX_CLIENTS; i++) + m_aSlots[i].m_Connection.Init(m_Socket); + + return true; +} + +int CNetConsole::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser) +{ + m_pfnNewClient = pfnNewClient; + m_pfnDelClient = pfnDelClient; + m_UserPtr = pUser; + return 0; +} + +int CNetConsole::Close() +{ + // TODO: implement me + return 0; +} + +int CNetConsole::Drop(int ClientID, const char *pReason) +{ + NETADDR Addr = ClientAddr(ClientID); + + char aAddrStr[NETADDR_MAXSTRSIZE]; + net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); + + if(m_pfnDelClient) + m_pfnDelClient(ClientID, pReason, m_UserPtr); + + m_aSlots[ClientID].m_Connection.Disconnect(pReason); + + return 0; +} + +int CNetConsole::AcceptClient(NETSOCKET Socket, const NETADDR *pAddr) +{ + char aError[256] = { 0 }; + int FreeSlot = -1; + + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + if(FreeSlot == -1 && m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE) + 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) + { + str_copy(aError, "Only one client per IP allowed", sizeof(aError)); + break; + } + } + } + + if(!aError[0] && FreeSlot != -1) + { + m_aSlots[FreeSlot].m_Connection.Init(Socket, pAddr); + if(m_pfnNewClient) + m_pfnNewClient(FreeSlot, m_UserPtr); + return 1; + } + + if(!aError[0]) + { + str_copy(aError, "No free slot available", sizeof(aError)); + } + + dbg_msg("netconsole", "refused client, reason=\"%s\"", aError); + + net_tcp_send(Socket, aError, str_length(aError)); + net_tcp_close(Socket); + + return 0; +} + +int CNetConsole::Update() +{ + NETSOCKET Socket; + NETADDR Addr; + + while(net_tcp_accept(m_Socket, &Socket, &Addr) > 0) + { + AcceptClient(Socket, &Addr); + } + + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ONLINE) + m_aSlots[i].m_Connection.Update(); + if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ERROR) + Drop(i, m_aSlots[i].m_Connection.ErrorString()); + } + + return 0; +} + +int CNetConsole::Recv(char *pLine, int MaxLength, int *pClientID) +{ + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ONLINE && m_aSlots[i].m_Connection.Recv(pLine, MaxLength)) + { + if(pClientID) + *pClientID = i; + return 1; + } + } + return 0; +} + +int CNetConsole::Broadcast(const char *pLine) +{ + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ONLINE) + Send(i, pLine); + } + return 0; +} + +int CNetConsole::Send(int ClientID, const char *pLine) +{ + return m_aSlots[ClientID].m_Connection.Send(pLine); +} + diff --git a/src/engine/shared/network_console_conn.cpp b/src/engine/shared/network_console_conn.cpp new file mode 100644 index 00000000..4dd971a6 --- /dev/null +++ b/src/engine/shared/network_console_conn.cpp @@ -0,0 +1,176 @@ +/* (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 "config.h" +#include "network.h" + +void CConsoleNetConnection::Reset() +{ + m_State = NET_CONNSTATE_OFFLINE; + mem_zero(&m_PeerAddr, sizeof(m_PeerAddr)); + m_aErrorString[0] = 0; + + m_aBuffer[0] = 0; + m_pBufferPos = 0; + m_Timeout = 0; +} + +void CConsoleNetConnection::Init(NETSOCKET Socket, const NETADDR *pAddr) +{ + Reset(); + + m_Socket = Socket; + net_tcp_set_non_blocking(m_Socket); + + m_LastRecvTime = time_get(); + + m_PeerAddr = *pAddr; + m_State = NET_CONNSTATE_ONLINE; +} + +void CConsoleNetConnection::Init(NETSOCKET Socket) +{ + Reset(); + + m_Socket = Socket; + net_tcp_set_non_blocking(m_Socket); + + m_LastRecvTime = time_get(); +} + +int CConsoleNetConnection::Connect(const NETADDR *pAddr) +{ + if(State() != NET_CONNSTATE_OFFLINE) + return -1; + + // init connection + Reset(); + m_PeerAddr = *pAddr; + net_tcp_connect(m_Socket, pAddr); + m_State = NET_CONNSTATE_ONLINE; + return 0; +} + +void CConsoleNetConnection::Disconnect(const char *pReason) +{ + if(State() == NET_CONNSTATE_OFFLINE) + return; + + if(pReason) + { + char aBuf[sizeof(pReason) + 4]; + str_format(aBuf, sizeof(aBuf), "%s", pReason); + Send(aBuf); + } + + net_tcp_close(m_Socket); + + Reset(); +} + +int CConsoleNetConnection::Update() +{ + if(m_Timeout && time_get() > m_LastRecvTime + m_Timeout * time_freq()) + { + m_State = NET_CONNSTATE_ERROR; + str_copy(m_aErrorString, "timeout", sizeof(m_aErrorString)); + return -1; + } + + if(State() == NET_CONNSTATE_ONLINE) + { + char aBuf[NET_MAX_PACKETSIZE]; + + int Bytes = net_tcp_recv(m_Socket, aBuf, sizeof(aBuf) - 1); + + if(Bytes > 0) + { + aBuf[Bytes - 1] = 0; + + if(!m_pBufferPos) + m_aBuffer[0] = 0; + else if(m_pBufferPos != m_aBuffer) + mem_move(m_pBufferPos, m_aBuffer, str_length(m_pBufferPos) + 1); // +1 for the \0 + m_pBufferPos = m_aBuffer; + + str_append(m_aBuffer, aBuf, sizeof(m_aBuffer)); + + m_LastRecvTime = time_get(); + } + else if(Bytes < 0) + { + if(net_would_block()) // no data received + return 0; + + m_State = NET_CONNSTATE_ERROR; // error + str_copy(m_aErrorString, "connection failure", sizeof(m_aErrorString)); + return -1; + } + else + { + m_State = NET_CONNSTATE_ERROR; + str_copy(m_aErrorString, "remote end closed the connection", sizeof(m_aErrorString)); + return -1; + } + } + + return 0; +} + +int CConsoleNetConnection::Recv(char *pLine, int MaxLength) +{ + if(State() == NET_CONNSTATE_ONLINE) + { + if(m_pBufferPos && *m_pBufferPos) + { + char *pResult = m_pBufferPos; + + while(*m_pBufferPos && *m_pBufferPos != '\r' && *m_pBufferPos != '\n') + m_pBufferPos++; + + if(*m_pBufferPos) // haven't reached the end of the buffer? + { + if(*m_pBufferPos == '\r' && *(m_pBufferPos + 1) == '\n') + { + *m_pBufferPos = 0; + m_pBufferPos += 2; + } + else + { + *m_pBufferPos = 0; + m_pBufferPos++; + } + } + else + { + m_pBufferPos = 0; + } + + str_copy(pLine, pResult, MaxLength); + return 1; + } + } + return 0; +} + +int CConsoleNetConnection::Send(const char *pLine) +{ + if(State() != NET_CONNSTATE_ONLINE) + return -1; + + int Length = str_length(pLine); + char aBuf[1024]; + str_copy(aBuf, pLine, sizeof(aBuf) - 2); + aBuf[Length + 1] = '\n'; + aBuf[Length + 2] = '\0'; + + if(net_tcp_send(m_Socket, aBuf, Length + 2) < 0) + { + m_State = NET_CONNSTATE_ERROR; + str_copy(m_aErrorString, "Failed to send packet", sizeof(m_aErrorString)); + return -1; + } + + return 0; +} + -- cgit 1.4.1 From b0fdc4095988ed5bd8bda4b94ce35bc506f31653 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Sun, 24 Jul 2011 12:13:33 +0200 Subject: deleted unnecessary empty files --- src/engine/server/econ.cpp | 0 src/engine/server/econ.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/engine/server/econ.cpp delete mode 100644 src/engine/server/econ.h diff --git a/src/engine/server/econ.cpp b/src/engine/server/econ.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/engine/server/econ.h b/src/engine/server/econ.h deleted file mode 100644 index e69de29b..00000000 -- cgit 1.4.1 From a0a62bcd70d1d8c0874d5ff52e443b5fb417854c Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 13:40:01 +0200 Subject: fixed econ feature and tcp --- src/base/system.c | 44 +++++--- src/engine/console.h | 5 +- src/engine/server/server.cpp | 127 +++------------------ src/engine/server/server.h | 29 +---- src/engine/shared/config_variables.h | 10 +- src/engine/shared/console.cpp | 32 ++++-- src/engine/shared/console.h | 12 +- src/engine/shared/econ.cpp | 147 ++++++++++++++++++++++++ src/engine/shared/econ.h | 43 ++++++++ src/engine/shared/network.h | 24 ++-- src/engine/shared/network_console.cpp | 49 +++----- src/engine/shared/network_console_conn.cpp | 172 +++++++++++++++-------------- src/game/client/components/console.cpp | 14 ++- src/game/client/components/console.h | 2 + 14 files changed, 408 insertions(+), 302 deletions(-) create mode 100644 src/engine/shared/econ.cpp create mode 100644 src/engine/shared/econ.h diff --git a/src/base/system.c b/src/base/system.c index 551b3f1b..466e3ca6 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -42,10 +42,6 @@ #include #include #include - - #ifndef EWOULDBLOCK - #define EWOULDBLOCK WSAEWOULDBLOCK - #endif #else #error NOT IMPLEMENTED #endif @@ -1102,30 +1098,31 @@ int net_set_blocking(NETSOCKET sock) int net_tcp_listen(NETSOCKET sock, int backlog) { + int err = -1; if(sock.ipv4sock >= 0) - listen(sock.ipv4sock, backlog); + err = listen(sock.ipv4sock, backlog); if(sock.ipv6sock >= 0) - listen(sock.ipv6sock, backlog); - return 0; + err = listen(sock.ipv6sock, backlog); + return err; } int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) { int s; socklen_t sockaddr_len; - struct sockaddr addr; *new_sock = invalid_socket; - sockaddr_len = sizeof(addr); - if(sock.ipv4sock >= 0) { - s = accept(sock.ipv4sock, &addr, &sockaddr_len); + struct sockaddr_in addr; + sockaddr_len = sizeof(addr); + s = accept(sock.ipv4sock, (struct sockaddr *)&addr, &sockaddr_len); + if (s != -1) { - sockaddr_to_netaddr(&addr, a); + sockaddr_to_netaddr((const struct sockaddr *)&addr, a); new_sock->type = NETTYPE_IPV4; new_sock->ipv4sock = s; return s; @@ -1134,18 +1131,21 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a) if(sock.ipv6sock >= 0) { - s = accept(sock.ipv6sock, &addr, &sockaddr_len); + struct sockaddr_in6 addr; + sockaddr_len = sizeof(addr); + s = accept(sock.ipv6sock, (struct sockaddr *)&addr, &sockaddr_len); + if (s != -1) { - sockaddr_to_netaddr(&addr, a); + sockaddr_to_netaddr((const struct sockaddr *)&addr, a); new_sock->type = NETTYPE_IPV6; new_sock->ipv6sock = s; return s; } } - return 0; + return -1; } int net_tcp_connect(NETSOCKET sock, const NETADDR *a) @@ -1164,7 +1164,7 @@ int net_tcp_connect(NETSOCKET sock, const NETADDR *a) return connect(sock.ipv6sock, (struct sockaddr *)&addr, sizeof(addr)); } - return 0; + return -1; } int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr) @@ -1180,7 +1180,7 @@ int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr) int net_tcp_send(NETSOCKET sock, const void *data, int size) { - int bytes = 0; + int bytes = -1; if(sock.ipv4sock >= 0) bytes = send((int)sock.ipv4sock, (const char*)data, size, 0); @@ -1192,7 +1192,7 @@ int net_tcp_send(NETSOCKET sock, const void *data, int size) int net_tcp_recv(NETSOCKET sock, void *data, int maxsize) { - int bytes = 0; + int bytes = -1; if(sock.ipv4sock >= 0) bytes = recv((int)sock.ipv4sock, (char*)data, maxsize, 0); @@ -1209,12 +1209,20 @@ int net_tcp_close(NETSOCKET sock) int net_errno() { +#if defined(CONF_FAMILY_WINDOWS) + return WSAGetLastError(); +#else return errno; +#endif } int net_would_block() { +#if defined(CONF_FAMILY_WINDOWS) + return net_errno() == WSAEWOULDBLOCK; +#else return net_errno() == EWOULDBLOCK; +#endif } int net_init() diff --git a/src/engine/console.h b/src/engine/console.h index 7c39cf49..5d3f2811 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -23,6 +23,8 @@ public: TEMPCMD_NAME_LENGTH=32, TEMPCMD_HELP_LENGTH=64, TEMPCMD_PARAMS_LENGTH=16, + + MAX_PRINT_CB=4, }; // TODO: rework this interface to reduce the amount of virtual calls @@ -79,7 +81,8 @@ public: virtual void ExecuteLineStroked(int Stroke, const char *pStr) = 0; virtual void ExecuteFile(const char *pFilename) = 0; - virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData) = 0; + virtual int RegisterPrintCallback(int OutputLevel, FPrintCallback pfnPrintCallback, void *pUserData) = 0; + virtual void SetPrintOutputLevel(int Index, int OutputLevel) = 0; virtual void Print(int Level, const char *pFrom, const char *pStr) = 0; virtual void SetAccessLevel(int AccessLevel) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 8e151035..ee7de31b 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -317,15 +318,8 @@ int CServer::Init() m_aClients[i].m_Snapshots.Init(); } - for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) - { - m_aEconClients[i].m_State = CEconClient::STATE_EMPTY; - } - m_CurrentGameTick = 0; - m_UseEcon = 0; - return 0; } @@ -618,30 +612,6 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) return 0; } -int CServer::NewConsoleClientCallback(int EconID, void *pUser) -{ - CServer *pThis = (CServer *)pUser; - pThis->m_aEconClients[EconID].m_State = CEconClient::STATE_CONNECTED; - pThis->m_NetConsole.SetTimeout(EconID, g_Config.m_SvEconAuthTimeout); - return 0; -} - -int CServer::DelConsoleClientCallback(int EconID, const char *pReason, void *pUser) -{ - CServer *pThis = (CServer *)pUser; - - NETADDR Addr = pThis->m_NetConsole.ClientAddr(EconID); - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "econ client dropped. eid=%d addr=%s reason='%s'", EconID, aAddrStr, pReason); - pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); - - pThis->m_aEconClients[EconID].m_State = CEconClient::STATE_EMPTY; - return 0; -} - - void CServer::SendMap(int ClientID) { CMsgPacker Msg(NETMSG_MAP_CHANGE); @@ -664,12 +634,7 @@ void CServer::SendRconLine(int ClientID, const char *pLine) SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); } -void CServer::SendEconLine(int EconID, const char *pLine) -{ - m_NetConsole.Send(EconID, pLine); -} - -void CServer::SendConsoleLineAuthed(const char *pLine, void *pUser) +void CServer::SendRconLineAuthed(const char *pLine, void *pUser) { CServer *pThis = (CServer *)pUser; static volatile int ReentryGuard = 0; @@ -684,15 +649,6 @@ void CServer::SendConsoleLineAuthed(const char *pLine, void *pUser) pThis->SendRconLine(i, pLine); } - if(pThis->m_UseEcon) - { - for(i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) - { - if(pThis->m_aEconClients[i].m_State == CEconClient::STATE_AUTHED) - pThis->SendEconLine(i, pLine); - } - } - ReentryGuard--; } @@ -1130,46 +1086,7 @@ void CServer::PumpNetwork() ProcessClientPacket(&Packet); } - if(m_UseEcon) - EconPumpNetwork(); -} - -void CServer::EconPumpNetwork() -{ - m_NetConsole.Update(); - - char aBuf[NET_MAX_PACKETSIZE]; - int EconID; - - while(m_NetConsole.Recv(aBuf, sizeof(aBuf) - 1, &EconID)) - { - dbg_assert(m_aEconClients[EconID].m_State != CEconClient::STATE_EMPTY, "got message from empty slot"); - if(m_aEconClients[EconID].m_State == CEconClient::STATE_CONNECTED) - { - if(str_comp(aBuf, g_Config.m_SvRconPassword) == 0) - { - m_aEconClients[EconID].m_State = CEconClient::STATE_AUTHED; - m_NetConsole.Send(EconID, "Authentication successful. Remote console access granted."); - m_NetConsole.SetTimeout(EconID, g_Config.m_SvEconTimeout); - - str_format(aBuf, sizeof(aBuf), "EconID=%d authed", EconID); - Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); - } - else - { - m_NetConsole.Send(EconID, "Wrong password"); - } - } - else if(m_aEconClients[EconID].m_State == CEconClient::STATE_AUTHED) - { - char aFormatted[256]; - str_format(aFormatted, sizeof(aBuf), "eid=%d cmd='%s'", EconID, aBuf); - Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aFormatted); - m_RconClientID = EconID; - Console()->ExecuteLine(aBuf); - m_RconClientID = -1; - } - } + m_Econ.Update(); } char *CServer::GetMapName() @@ -1244,7 +1161,7 @@ int CServer::Run() m_pStorage = Kernel()->RequestInterface(); // - Console()->RegisterPrintCallback(SendConsoleLineAuthed, this); + m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, SendRconLineAuthed, this); // load map if(!LoadMap(g_Config.m_SvMap)) @@ -1275,30 +1192,7 @@ int CServer::Run() m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this); - if(g_Config.m_SvEconPort && g_Config.m_SvRconPassword[0]) - { - dbg_msg("econ", "binding econ to %s:%d", g_Config.m_SvEconBindaddr, g_Config.m_SvEconPort); - if(g_Config.m_SvEconBindaddr[0] && net_host_lookup(g_Config.m_SvEconBindaddr, &BindAddr, NETTYPE_ALL) == 0) - { - BindAddr.port = g_Config.m_SvEconPort; - } - else - { - mem_zero(&BindAddr, sizeof(BindAddr)); - BindAddr.type = NETTYPE_ALL; - BindAddr.port = g_Config.m_SvEconPort; - } - - if(m_NetConsole.Open(BindAddr, 0)) - { - m_NetConsole.SetCallbacks(NewConsoleClientCallback, DelConsoleClientCallback, this); - m_UseEcon = 1; - } - else - { - dbg_msg("econ", "couldn't open econ socket. port might already be in use"); - } - } + m_Econ.Init(Console()); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "server name is '%s'", g_Config.m_SvName); @@ -1694,6 +1588,16 @@ void CServer::ConchainModCommandUpdate(IConsole::IResult *pResult, void *pUserDa pfnCallback(pResult, pCallbackUserData); } +void CServer::ConchainConsoleOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments() == 1) + { + CServer *pThis = static_cast(pUserData); + pThis->Console()->SetPrintOutputLevel(pThis->m_PrintCBIndex, pResult->GetInteger(0)); + } +} + void CServer::RegisterCommands() { m_pConsole = Kernel()->RequestInterface(); @@ -1715,6 +1619,7 @@ void CServer::RegisterCommands() Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this); Console()->Chain("mod_command", ConchainModCommandUpdate, this); + Console()->Chain("console_output_level", ConchainConsoleOutputLevelUpdate, this); } diff --git a/src/engine/server/server.h b/src/engine/server/server.h index d744b9ff..4e575055 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -109,26 +109,11 @@ public: CClient m_aClients[MAX_CLIENTS]; - class CEconClient - { - public: - enum - { - STATE_EMPTY=0, - STATE_CONNECTED, - STATE_AUTHED - }; - - int m_State; - }; - - CEconClient m_aEconClients[NET_MAX_CONSOLE_CLIENTS]; - CSnapshotDelta m_SnapshotDelta; CSnapshotBuilder m_SnapshotBuilder; CSnapIDPool m_IDPool; CNetServer m_NetServer; - CNetConsole m_NetConsole; + CEcon m_Econ; IEngineMap *m_pMap; @@ -138,8 +123,7 @@ public: int m_MapReload; int m_RconClientID; int m_RconAuthLevel; - - int m_UseEcon; + int m_PrintCBIndex; int64 m_Lastheartbeat; //static NETADDR4 master_server; @@ -186,14 +170,10 @@ public: static int NewClientCallback(int ClientID, void *pUser); static int DelClientCallback(int ClientID, const char *pReason, void *pUser); - static int NewConsoleClientCallback(int EconID, void *pUser); - static int DelConsoleClientCallback(int EconID, const char *pReason, void *pUser); - void SendMap(int ClientID); void SendConnectionReady(int ClientID); void SendRconLine(int ClientID, const char *pLine); - void SendEconLine(int EconID, const char *pLine); - static void SendConsoleLineAuthed(const char *pLine, void *pUser); + static void SendRconLineAuthed(const char *pLine, void *pUser); void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID); void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID); @@ -207,8 +187,6 @@ public: int BanAdd(NETADDR Addr, int Seconds, const char *pReason); int BanRemove(NETADDR Addr); - void EconPumpNetwork(); - void PumpNetwork(); char *GetMapName(); @@ -229,6 +207,7 @@ public: 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); + static void ConchainConsoleOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); void RegisterCommands(); diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index fd318a7d..cb8f5f15 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -86,10 +86,12 @@ MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remo MACRO_CONFIG_STR(SvRconModPassword, sv_rcon_mod_password, 32, "", CFGFLAG_SERVER, "Remote console password for moderators (limited access)") MACRO_CONFIG_INT(SvRconMaxTries, sv_rcon_max_tries, 3, 0, 100, CFGFLAG_SERVER, "Maximum number of tries for remote console authentication") MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if remote console authentication fails. 0 makes it just use kick") -MACRO_CONFIG_STR(SvEconBindaddr, sv_econ_bindaddr, 128, "localhost", CFGFLAG_SERVER, "Address to bind the external console to. Anything but 'localhost' is dangerous") -MACRO_CONFIG_INT(SvEconPort, sv_econ_port, 0, 0, 0, CFGFLAG_SERVER, "Port to use for the external console") -MACRO_CONFIG_INT(SvEconAuthTimeout, sv_econ_auth_timeout, 30, 1, 120, CFGFLAG_SERVER, "Time in seconds before the the econ authentification times out") -MACRO_CONFIG_INT(SvEconTimeout, sv_econ_timeout, 300, 1, 3600, CFGFLAG_SERVER, "Time in seconds before the econ connection times out") + +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(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_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 847fb140..e4cb1991 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -173,20 +173,34 @@ int CConsole::ParseArgs(CResult *pResult, const char *pFormat) return Error; } -void CConsole::RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData) +int CConsole::RegisterPrintCallback(int OutputLevel, FPrintCallback pfnPrintCallback, void *pUserData) { - m_pfnPrintCallback = pfnPrintCallback; - m_pPrintCallbackUserdata = pUserData; + if(m_NumPrintCB == MAX_PRINT_CB) + return -1; + + m_aPrintCB[m_NumPrintCB].m_OutputLevel = clamp(OutputLevel, (int)(OUTPUT_LEVEL_STANDARD), (int)(OUTPUT_LEVEL_DEBUG)); + m_aPrintCB[m_NumPrintCB].m_pfnPrintCallback = pfnPrintCallback; + m_aPrintCB[m_NumPrintCB].m_pPrintCallbackUserdata = pUserData; + return m_NumPrintCB++; +} + +void CConsole::SetPrintOutputLevel(int Index, int OutputLevel) +{ + if(Index >= 0 && Index < MAX_PRINT_CB) + m_aPrintCB[Index].m_OutputLevel = clamp(OutputLevel, (int)(OUTPUT_LEVEL_STANDARD), (int)(OUTPUT_LEVEL_DEBUG)); } void CConsole::Print(int Level, const char *pFrom, const char *pStr) { dbg_msg(pFrom ,"%s", pStr); - if(Level <= g_Config.m_ConsoleOutputLevel && m_pfnPrintCallback) + for(int i = 0; i < m_NumPrintCB; ++i) { - char aBuf[1024]; - str_format(aBuf, sizeof(aBuf), "[%s]: %s", pFrom, pStr); - m_pfnPrintCallback(aBuf, m_pPrintCallbackUserdata); + if(Level <= m_aPrintCB[i].m_OutputLevel && m_aPrintCB[i].m_pfnPrintCallback) + { + char aBuf[1024]; + str_format(aBuf, sizeof(aBuf), "[%s]: %s", pFrom, pStr); + m_aPrintCB[i].m_pfnPrintCallback(aBuf, m_aPrintCB[i].m_pPrintCallbackUserdata); + } } } @@ -562,8 +576,8 @@ CConsole::CConsole(int FlagMask) m_ExecutionQueue.Reset(); m_pFirstCommand = 0; m_pFirstExec = 0; - m_pPrintCallbackUserdata = 0; - m_pfnPrintCallback = 0; + mem_zero(m_aPrintCB, sizeof(m_aPrintCB)); + m_NumPrintCB = 0; m_pStorage = 0; diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index b29f3202..6989c696 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -60,8 +60,13 @@ class CConsole : public IConsole void ExecuteFileRecurse(const char *pFilename); void ExecuteLineStroked(int Stroke, const char *pStr); - FPrintCallback m_pfnPrintCallback; - void *m_pPrintCallbackUserdata; + struct + { + int m_OutputLevel; + FPrintCallback m_pfnPrintCallback; + void *m_pPrintCallbackUserdata; + } m_aPrintCB[MAX_PRINT_CB]; + int m_NumPrintCB; enum { @@ -167,7 +172,8 @@ public: virtual void ExecuteLine(const char *pStr); virtual void ExecuteFile(const char *pFilename); - virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData); + virtual int RegisterPrintCallback(int OutputLevel, FPrintCallback pfnPrintCallback, void *pUserData); + virtual void SetPrintOutputLevel(int Index, int OutputLevel); virtual void Print(int Level, const char *pFrom, const char *pStr); void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_MOD)); } diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp new file mode 100644 index 00000000..ba86e5c0 --- /dev/null +++ b/src/engine/shared/econ.cpp @@ -0,0 +1,147 @@ +#include +#include + +#include "econ.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)); + 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); + + pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTED; + pThis->m_aClients[ClientID].m_TimeConnected = time_get(); + return 0; +} + +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)); + 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); + + pThis->m_aClients[ClientID].m_State = CClient::STATE_EMPTY; + return 0; +} + +void CEcon::SendLineCB(const char *pLine, void *pUserData) +{ + static_cast(pUserData)->Send(-1, pLine); +} + +void CEcon::ConchainEconOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments() == 1) + { + CEcon *pThis = static_cast(pUserData); + pThis->Console()->SetPrintOutputLevel(pThis->m_PrintCBIndex, pResult->GetInteger(0)); + } +} + +void CEcon::Init(IConsole *pConsole) +{ + m_pConsole = pConsole; + + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + m_aClients[i].m_State = CClient::STATE_EMPTY; + + m_Ready = false; + + if(g_Config.m_EcPort == 0 || g_Config.m_EcPassword[0] == 0) + return; + + NETADDR BindAddr; + if(g_Config.m_EcBindaddr[0] && net_host_lookup(g_Config.m_EcBindaddr, &BindAddr, NETTYPE_ALL) == 0) + BindAddr.port = g_Config.m_EcPort; + else + { + mem_zero(&BindAddr, sizeof(BindAddr)); + BindAddr.type = NETTYPE_ALL; + BindAddr.port = g_Config.m_EcPort; + } + + if(m_NetConsole.Open(BindAddr, 0)) + { + m_NetConsole.SetCallbacks(NewClientCallback, DelClientCallback, this); + m_Ready = true; + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "bound to %s:%d", g_Config.m_EcBindaddr, g_Config.m_EcPort); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,"econ", aBuf); + + Console()->Chain("ec_output_level", ConchainEconOutputLevelUpdate, this); + m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_EcOutputLevel, SendLineCB, this); + } + else + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,"econ", "couldn't open socket. port might already be in use"); +} + +void CEcon::Update() +{ + if(!m_Ready) + return; + + m_NetConsole.Update(); + + char aBuf[NET_MAX_PACKETSIZE]; + int ClientID; + + while(m_NetConsole.Recv(aBuf, (int)(sizeof(aBuf))-1, &ClientID)) + { + dbg_assert(m_aClients[ClientID].m_State != CClient::STATE_EMPTY, "got message from empty slot"); + if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTED) + { + if(str_comp(aBuf, g_Config.m_EcPassword) == 0) + { + m_aClients[ClientID].m_State = CClient::STATE_AUTHED; + m_NetConsole.Send(ClientID, "Authentication successful. External console access granted."); + + str_format(aBuf, sizeof(aBuf), "cid=%d authed", ClientID); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "econ", aBuf); + } + else + m_NetConsole.Send(ClientID, "Wrong password"); + } + else if(m_aClients[ClientID].m_State == CClient::STATE_AUTHED) + { + char aFormatted[256]; + str_format(aFormatted, sizeof(aBuf), "cid=%d cmd='%s'", ClientID, aBuf); + Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aFormatted); + Console()->ExecuteLine(aBuf); + } + } + + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; ++i) + { + if(m_aClients[i].m_State == CClient::STATE_CONNECTED && + time_get() > m_aClients[i].m_TimeConnected + g_Config.m_EcAuthTimeout * time_freq()) + m_NetConsole.Drop(i, "authentication timeout"); + } +} + +void CEcon::Send(int ClientID, const char *pLine) +{ + if(!m_Ready) + return; + + if(ClientID == -1) + { + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + { + if(m_aClients[i].m_State == CClient::STATE_AUTHED) + m_NetConsole.Send(i, pLine); + } + } + else if(ClientID >= 0 && ClientID < NET_MAX_CONSOLE_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_AUTHED) + m_NetConsole.Send(ClientID, pLine); +} diff --git a/src/engine/shared/econ.h b/src/engine/shared/econ.h new file mode 100644 index 00000000..33b23ea6 --- /dev/null +++ b/src/engine/shared/econ.h @@ -0,0 +1,43 @@ +#ifndef ENGINE_SHARED_ECON_H +#define ENGINE_SHARED_ECON_H + +#include "network.h" + +class CEcon +{ + class CClient + { + public: + enum + { + STATE_EMPTY=0, + STATE_CONNECTED, + STATE_AUTHED, + }; + + int m_State; + int64 m_TimeConnected; + }; + CClient m_aClients[NET_MAX_CONSOLE_CLIENTS]; + + IConsole *m_pConsole; + CNetConsole m_NetConsole; + + bool m_Ready; + int m_PrintCBIndex; + + static void SendLineCB(const char *pLine, void *pUserData); + static void ConchainEconOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + + static int NewClientCallback(int ClientID, void *pUser); + static int DelClientCallback(int ClientID, const char *pReason, void *pUser); + +public: + IConsole *Console() { return m_pConsole; } + + void Init(IConsole *pConsole); + void Update(); + void Send(int ClientID, const char *pLine); +}; + +#endif diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index d0b78d05..94e2824c 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -49,7 +49,7 @@ enum NET_MAX_CHUNKHEADERSIZE = 5, NET_PACKETHEADERSIZE = 3, NET_MAX_CLIENTS = 16, - NET_MAX_CONSOLE_CLIENTS = 16, + NET_MAX_CONSOLE_CLIENTS = 4, NET_MAX_SEQUENCE = 1<<10, NET_SEQUENCE_MASK = NET_MAX_SEQUENCE-1, @@ -196,32 +196,27 @@ public: class CConsoleNetConnection { private: - unsigned m_State; + int m_State; NETADDR m_PeerAddr; NETSOCKET m_Socket; char m_aBuffer[NET_MAX_PACKETSIZE]; - char *m_pBufferPos; + int m_BufferOffset; char m_aErrorString[256]; - int m_Timeout; - int64 m_LastRecvTime; + bool m_LineEndingDetected; + char m_aLineEnding[3]; public: - void Init(NETSOCKET Socket); void Init(NETSOCKET Socket, const NETADDR *pAddr); - int Connect(const NETADDR *pAddr); void Disconnect(const char *pReason); int State() const { return m_State; } NETADDR PeerAddress() const { return m_PeerAddr; } const char *ErrorString() const { return m_aErrorString; } - void SetTimeout(int Timeout) { m_Timeout = Timeout; } - int Timeout() const { return m_Timeout; } - void Reset(); int Update(); int Send(const char *pLine); @@ -337,7 +332,7 @@ private: }; NETSOCKET m_Socket; - CSlot m_aSlots[NET_MAX_CLIENTS]; + CSlot m_aSlots[NET_MAX_CONSOLE_CLIENTS]; NETFUNC_NEWCLIENT m_pfnNewClient; NETFUNC_DELCLIENT m_pfnDelClient; @@ -346,14 +341,13 @@ private: CNetRecvUnpacker m_RecvUnpacker; public: - int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); + void SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); // bool Open(NETADDR BindAddr, int Flags); int Close(); // - int Broadcast(const char *pLine); int Recv(char *pLine, int MaxLength, int *pClientID = 0); int Send(int ClientID, const char *pLine); int Update(); @@ -362,11 +356,7 @@ public: int AcceptClient(NETSOCKET Socket, const NETADDR *pAddr); int Drop(int ClientID, const char *pReason); - // - void SetTimeout(int ClientID, int Timeout) { m_aSlots[ClientID].m_Connection.SetTimeout(Timeout); } - // status requests - int Timeout(int ClientID) { return m_aSlots[ClientID].m_Connection.Timeout(); } NETADDR ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } }; diff --git a/src/engine/shared/network_console.cpp b/src/engine/shared/network_console.cpp index 3e50a1ac..0cf2a718 100644 --- a/src/engine/shared/network_console.cpp +++ b/src/engine/shared/network_console.cpp @@ -9,25 +9,24 @@ bool CNetConsole::Open(NETADDR BindAddr, int Flags) mem_zero(this, sizeof(*this)); // open socket - m_Socket = net_tcp_create(&BindAddr); + m_Socket = net_tcp_create(BindAddr); if(!m_Socket.type) return false; if(net_tcp_listen(m_Socket, NET_MAX_CONSOLE_CLIENTS)) return false; - net_tcp_set_non_blocking(m_Socket); + net_set_non_blocking(m_Socket); - for(int i = 0; i < NET_MAX_CLIENTS; i++) - m_aSlots[i].m_Connection.Init(m_Socket); + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + m_aSlots[i].m_Connection.Reset(); return true; } -int CNetConsole::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser) +void CNetConsole::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser) { m_pfnNewClient = pfnNewClient; m_pfnDelClient = pfnDelClient; m_UserPtr = pUser; - return 0; } int CNetConsole::Close() @@ -38,11 +37,6 @@ int CNetConsole::Close() int CNetConsole::Drop(int ClientID, const char *pReason) { - NETADDR Addr = ClientAddr(ClientID); - - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr)); - if(m_pfnDelClient) m_pfnDelClient(ClientID, pReason, m_UserPtr); @@ -56,40 +50,39 @@ 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++) { if(FreeSlot == -1 && m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE) FreeSlot = i; if(m_aSlots[i].m_Connection.State() != NET_CONNSTATE_OFFLINE) { - NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress();; + NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); if(net_addr_comp(pAddr, &PeerAddr) == 0) { - str_copy(aError, "Only one client per IP allowed", sizeof(aError)); + str_copy(aError, "only one client per IP allowed", sizeof(aError)); break; } } } + // accept client if(!aError[0] && FreeSlot != -1) { m_aSlots[FreeSlot].m_Connection.Init(Socket, pAddr); if(m_pfnNewClient) m_pfnNewClient(FreeSlot, m_UserPtr); - return 1; + return 0; } + // reject client if(!aError[0]) - { - str_copy(aError, "No free slot available", sizeof(aError)); - } - - dbg_msg("netconsole", "refused client, reason=\"%s\"", aError); + str_copy(aError, "no free slot available", sizeof(aError)); net_tcp_send(Socket, aError, str_length(aError)); net_tcp_close(Socket); - return 0; + return -1; } int CNetConsole::Update() @@ -127,18 +120,10 @@ int CNetConsole::Recv(char *pLine, int MaxLength, int *pClientID) return 0; } -int CNetConsole::Broadcast(const char *pLine) -{ - for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) - { - if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ONLINE) - Send(i, pLine); - } - return 0; -} - int CNetConsole::Send(int ClientID, const char *pLine) { - return m_aSlots[ClientID].m_Connection.Send(pLine); + if(m_aSlots[ClientID].m_Connection.State() == NET_CONNSTATE_ONLINE) + return m_aSlots[ClientID].m_Connection.Send(pLine); + else + return -1; } - diff --git a/src/engine/shared/network_console_conn.cpp b/src/engine/shared/network_console_conn.cpp index 4dd971a6..75b581fa 100644 --- a/src/engine/shared/network_console_conn.cpp +++ b/src/engine/shared/network_console_conn.cpp @@ -1,7 +1,6 @@ /* (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 "config.h" #include "network.h" void CConsoleNetConnection::Reset() @@ -10,9 +9,22 @@ void CConsoleNetConnection::Reset() mem_zero(&m_PeerAddr, sizeof(m_PeerAddr)); m_aErrorString[0] = 0; + m_Socket.type = NETTYPE_INVALID; + m_Socket.ipv4sock = -1; + m_Socket.ipv6sock = -1; m_aBuffer[0] = 0; - m_pBufferPos = 0; - m_Timeout = 0; + m_BufferOffset = 0; + + m_LineEndingDetected = false; + #if defined(CONF_FAMILY_WINDOWS) + m_aLineEnding[0] = '\r'; + m_aLineEnding[1] = '\n'; + m_aLineEnding[2] = 0; + #else + m_aLineEnding[0] = '\n'; + m_aLineEnding[1] = 0; + m_aLineEnding[2] = 0; + #endif } void CConsoleNetConnection::Init(NETSOCKET Socket, const NETADDR *pAddr) @@ -20,48 +32,19 @@ void CConsoleNetConnection::Init(NETSOCKET Socket, const NETADDR *pAddr) Reset(); m_Socket = Socket; - net_tcp_set_non_blocking(m_Socket); - - m_LastRecvTime = time_get(); + net_set_non_blocking(m_Socket); m_PeerAddr = *pAddr; m_State = NET_CONNSTATE_ONLINE; } -void CConsoleNetConnection::Init(NETSOCKET Socket) -{ - Reset(); - - m_Socket = Socket; - net_tcp_set_non_blocking(m_Socket); - - m_LastRecvTime = time_get(); -} - -int CConsoleNetConnection::Connect(const NETADDR *pAddr) -{ - if(State() != NET_CONNSTATE_OFFLINE) - return -1; - - // init connection - Reset(); - m_PeerAddr = *pAddr; - net_tcp_connect(m_Socket, pAddr); - m_State = NET_CONNSTATE_ONLINE; - return 0; -} - void CConsoleNetConnection::Disconnect(const char *pReason) { if(State() == NET_CONNSTATE_OFFLINE) return; - if(pReason) - { - char aBuf[sizeof(pReason) + 4]; - str_format(aBuf, sizeof(aBuf), "%s", pReason); - Send(aBuf); - } + if(pReason && pReason[0]) + Send(pReason); net_tcp_close(m_Socket); @@ -70,32 +53,20 @@ void CConsoleNetConnection::Disconnect(const char *pReason) int CConsoleNetConnection::Update() { - if(m_Timeout && time_get() > m_LastRecvTime + m_Timeout * time_freq()) - { - m_State = NET_CONNSTATE_ERROR; - str_copy(m_aErrorString, "timeout", sizeof(m_aErrorString)); - return -1; - } - if(State() == NET_CONNSTATE_ONLINE) { - char aBuf[NET_MAX_PACKETSIZE]; + if((int)(sizeof(m_aBuffer)) <= m_BufferOffset) + { + m_State = NET_CONNSTATE_ERROR; + str_copy(m_aErrorString, "too weak connection (out of buffer)", sizeof(m_aErrorString)); + return -1; + } - int Bytes = net_tcp_recv(m_Socket, aBuf, sizeof(aBuf) - 1); + int Bytes = net_tcp_recv(m_Socket, m_aBuffer+m_BufferOffset, (int)(sizeof(m_aBuffer))-m_BufferOffset); if(Bytes > 0) { - aBuf[Bytes - 1] = 0; - - if(!m_pBufferPos) - m_aBuffer[0] = 0; - else if(m_pBufferPos != m_aBuffer) - mem_move(m_pBufferPos, m_aBuffer, str_length(m_pBufferPos) + 1); // +1 for the \0 - m_pBufferPos = m_aBuffer; - - str_append(m_aBuffer, aBuf, sizeof(m_aBuffer)); - - m_LastRecvTime = time_get(); + m_BufferOffset += Bytes; } else if(Bytes < 0) { @@ -121,32 +92,59 @@ int CConsoleNetConnection::Recv(char *pLine, int MaxLength) { if(State() == NET_CONNSTATE_ONLINE) { - if(m_pBufferPos && *m_pBufferPos) + if(m_BufferOffset) { - char *pResult = m_pBufferPos; - - while(*m_pBufferPos && *m_pBufferPos != '\r' && *m_pBufferPos != '\n') - m_pBufferPos++; - - if(*m_pBufferPos) // haven't reached the end of the buffer? + // find message start + int StartOffset = 0; + while(m_aBuffer[StartOffset] == '\r' || m_aBuffer[StartOffset] == '\n') { - if(*m_pBufferPos == '\r' && *(m_pBufferPos + 1) == '\n') + // detect clients line ending format + if(!m_LineEndingDetected) { - *m_pBufferPos = 0; - m_pBufferPos += 2; + m_aLineEnding[0] = m_aBuffer[StartOffset]; + if(StartOffset+1 < m_BufferOffset && (m_aBuffer[StartOffset+1] == '\r' || m_aBuffer[StartOffset+1] == '\n') && + m_aBuffer[StartOffset] != m_aBuffer[StartOffset+1]) + m_aLineEnding[1] = m_aBuffer[StartOffset+1]; + m_LineEndingDetected = true; } - else + + if(++StartOffset >= m_BufferOffset) { - *m_pBufferPos = 0; - m_pBufferPos++; + m_BufferOffset = 0; + return 0; } } - else + + // find message end + int EndOffset = StartOffset; + while(m_aBuffer[EndOffset] != '\r' && m_aBuffer[EndOffset] != '\n') { - m_pBufferPos = 0; + if(++EndOffset >= m_BufferOffset) + { + if(StartOffset > 0) + { + mem_move(m_aBuffer, m_aBuffer+StartOffset, m_BufferOffset-StartOffset); + m_BufferOffset -= StartOffset; + } + return 0; + } } - str_copy(pLine, pResult, MaxLength); + // extract message and update buffer + if(MaxLength-1 < EndOffset-StartOffset) + { + if(StartOffset > 0) + { + mem_move(m_aBuffer, m_aBuffer+StartOffset, m_BufferOffset-StartOffset); + m_BufferOffset -= StartOffset; + } + return 0; + } + mem_copy(pLine, m_aBuffer+StartOffset, EndOffset-StartOffset); + pLine[EndOffset-StartOffset] = 0; + str_sanitize_cc(pLine); + mem_move(m_aBuffer, m_aBuffer+EndOffset, m_BufferOffset-EndOffset); + m_BufferOffset -= EndOffset; return 1; } } @@ -158,19 +156,31 @@ int CConsoleNetConnection::Send(const char *pLine) if(State() != NET_CONNSTATE_ONLINE) return -1; - int Length = str_length(pLine); char aBuf[1024]; - str_copy(aBuf, pLine, sizeof(aBuf) - 2); - aBuf[Length + 1] = '\n'; - aBuf[Length + 2] = '\0'; - - if(net_tcp_send(m_Socket, aBuf, Length + 2) < 0) + str_copy(aBuf, pLine, (int)(sizeof(aBuf))-2); + int Length = str_length(aBuf); + aBuf[Length] = m_aLineEnding[0]; + aBuf[Length+1] = m_aLineEnding[1]; + aBuf[Length+2] = m_aLineEnding[2]; + Length += 3; + const char *pData = aBuf; + + while(true) { - m_State = NET_CONNSTATE_ERROR; - str_copy(m_aErrorString, "Failed to send packet", sizeof(m_aErrorString)); - return -1; + int Send = net_tcp_send(m_Socket, pData, Length); + if(Send < 0) + { + m_State = NET_CONNSTATE_ERROR; + str_copy(m_aErrorString, "failed to send packet", sizeof(m_aErrorString)); + return -1; + } + + if(Send >= Length) + break; + + pData += Send; + Length -= Send; } return 0; } - diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index 9b16ce0d..f2e9e65d 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -662,6 +662,16 @@ void CGameConsole::ClientConsolePrintCallback(const char *pStr, void *pUserData) ((CGameConsole *)pUserData)->m_LocalConsole.PrintLine(pStr); } +void CGameConsole::ConchainConsoleOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments() == 1) + { + CGameConsole *pThis = static_cast(pUserData); + pThis->Console()->SetPrintOutputLevel(pThis->m_PrintCBIndex, pResult->GetInteger(0)); + } +} + void CGameConsole::PrintLine(int Type, const char *pLine) { if(Type == CONSOLETYPE_LOCAL) @@ -679,7 +689,7 @@ void CGameConsole::OnConsoleInit() m_pConsole = Kernel()->RequestInterface(); // - Console()->RegisterPrintCallback(ClientConsolePrintCallback, this); + m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, ClientConsolePrintCallback, this); Console()->Register("toggle_local_console", "", CFGFLAG_CLIENT, ConToggleLocalConsole, this, "Toggle local console"); Console()->Register("toggle_remote_console", "", CFGFLAG_CLIENT, ConToggleRemoteConsole, this, "Toggle remote console"); @@ -687,6 +697,8 @@ void CGameConsole::OnConsoleInit() Console()->Register("clear_remote_console", "", CFGFLAG_CLIENT, ConClearRemoteConsole, this, "Clear remote console"); Console()->Register("dump_local_console", "", CFGFLAG_CLIENT, ConDumpLocalConsole, this, "Dump local console"); Console()->Register("dump_remote_console", "", CFGFLAG_CLIENT, ConDumpRemoteConsole, this, "Dump remote console"); + + Console()->Chain("console_output_level", ConchainConsoleOutputLevelUpdate, this); } void CGameConsole::OnStateChange(int NewState, int OldState) diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h index 326fb076..6bcc75a6 100644 --- a/src/game/client/components/console.h +++ b/src/game/client/components/console.h @@ -60,6 +60,7 @@ class CGameConsole : public CComponent CInstance *CurrentConsole(); float TimeNow(); + int m_PrintCBIndex; int m_ConsoleType; int m_ConsoleState; @@ -77,6 +78,7 @@ class CGameConsole : public CComponent static void ConClearRemoteConsole(IConsole::IResult *pResult, void *pUserData); static void ConDumpLocalConsole(IConsole::IResult *pResult, void *pUserData); static void ConDumpRemoteConsole(IConsole::IResult *pResult, void *pUserData); + static void ConchainConsoleOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); public: enum -- cgit 1.4.1 From b3e8506f20ac42902e575c4522502da94bace3ed Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 13:50:22 +0200 Subject: create client on heap. Closes #744 --- src/engine/client/client.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 90131703..37fda6c2 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2342,7 +2342,7 @@ void CClient::RegisterCommands() m_pConsole->Chain("br_filter_serveraddress", ConchainServerBrowserUpdate, this); } -static CClient m_Client; +static CClient *CreateClient() { return new CClient(); } /* Server Time @@ -2373,9 +2373,10 @@ int main(int argc, const char **argv) // ignore_convention } #endif + CClient *pClient = CreateClient(); IKernel *pKernel = IKernel::Create(); - pKernel->RegisterInterface(&m_Client); - m_Client.RegisterInterfaces(); + pKernel->RegisterInterface(pClient); + pClient->RegisterInterfaces(); // create the components IEngine *pEngine = CreateEngine("Teeworlds"); @@ -2428,12 +2429,12 @@ int main(int argc, const char **argv) // ignore_convention pEngineMasterServer->Load(); // register all console commands - m_Client.RegisterCommands(); + pClient->RegisterCommands(); pKernel->RequestInterface()->OnConsoleInit(); // init client's interfaces - m_Client.InitInterfaces(); + pClient->InitInterfaces(); // execute config file pConsole->ExecuteFile("settings.cfg"); @@ -2448,11 +2449,11 @@ int main(int argc, const char **argv) // ignore_convention // restore empty config strings to their defaults pConfig->RestoreStrings(); - m_Client.Engine()->InitLogfile(); + pClient->Engine()->InitLogfile(); // run the client dbg_msg("client", "starting..."); - m_Client.Run(); + pClient->Run(); // write down the config and quit pConfig->Save(); -- cgit 1.4.1 From 7db6d1e0567ee439e67c83a0ef670db9b419cfb6 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 18:08:24 +0200 Subject: fixed problem with player collision. Closes #722 --- src/game/gamecore.cpp | 48 ++++++++++++++++++---------------- src/game/server/entities/character.cpp | 2 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index d2a1652c..af086df2 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -362,35 +362,37 @@ void CCharacterCore::Move() m_Vel.x = m_Vel.x*RampValue; - vec2 NewPos = m_Pos; + vec2 NewPos = m_Pos; m_pCollision->MoveBox(&NewPos, &m_Vel, vec2(28.0f, 28.0f), 0); m_Vel.x = m_Vel.x*(1.0f/RampValue); if(m_pWorld && m_pWorld->m_Tuning.m_PlayerCollision) { - // check player collision - float Distance = distance(m_Pos, NewPos); - int End = Distance+1; - for(int i = 0; i < End; i++) - { - float a = i/Distance; - vec2 Pos = mix(m_Pos, NewPos, a); - for(int p = 0; p < MAX_CLIENTS; p++) - { - CCharacterCore *pCharCore = m_pWorld->m_apCharacters[p]; - if(!pCharCore || pCharCore == this) - continue; - float D = distance(Pos, pCharCore->m_Pos); - if(D < 28.0f*1.25f && D > 0.0f) - { - if(a > 0.0f) - m_Pos = Pos; - else - m_Pos = NewPos; - return; - } - } + // check player collision + float Distance = distance(m_Pos, NewPos); + int End = Distance+1; + vec2 LastPos = m_Pos; + for(int i = 0; i < End; i++) + { + float a = i/Distance; + vec2 Pos = mix(m_Pos, NewPos, a); + for(int p = 0; p < MAX_CLIENTS; p++) + { + CCharacterCore *pCharCore = m_pWorld->m_apCharacters[p]; + if(!pCharCore || pCharCore == this) + continue; + float D = distance(Pos, pCharCore->m_Pos); + if(D < 28.0f && D > 0.0f) + { + if(a > 0.0f) + m_Pos = LastPos; + else if(distance(NewPos, pCharCore->m_Pos) > D) + m_Pos = NewPos; + return; + } + } + LastPos = Pos; } } diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 9e2033b2..e926c305 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -179,7 +179,7 @@ void CCharacter::HandleNinja() if(m_NumObjectsHit < 10) m_apHitObjects[m_NumObjectsHit++] = aEnts[i]; - aEnts[i]->TakeDamage(vec2(0, 10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA); + aEnts[i]->TakeDamage(vec2(0, -10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA); } } -- cgit 1.4.1 From 0f11cf014c7a53c20d4432ea26af41123f9f2436 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 18:19:15 +0200 Subject: increased length for help string of temporary commands --- src/engine/console.h | 2 +- src/engine/server/server.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/console.h b/src/engine/console.h index 5d3f2811..0abf4ad2 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -21,7 +21,7 @@ public: ACCESS_LEVEL_MOD, TEMPCMD_NAME_LENGTH=32, - TEMPCMD_HELP_LENGTH=64, + TEMPCMD_HELP_LENGTH=96, TEMPCMD_PARAMS_LENGTH=16, MAX_PRINT_CB=4, diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index ee7de31b..46f87840 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -655,9 +655,9 @@ void CServer::SendRconLineAuthed(const char *pLine, void *pUser) void CServer::SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID) { CMsgPacker Msg(NETMSG_RCON_CMD_ADD); - Msg.AddString(pCommandInfo->m_pName, 32); - Msg.AddString(pCommandInfo->m_pHelp, 64); - Msg.AddString(pCommandInfo->m_pParams, 16); + Msg.AddString(pCommandInfo->m_pName, IConsole::TEMPCMD_NAME_LENGTH); + Msg.AddString(pCommandInfo->m_pHelp, IConsole::TEMPCMD_HELP_LENGTH); + Msg.AddString(pCommandInfo->m_pParams, IConsole::TEMPCMD_PARAMS_LENGTH); SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); } -- cgit 1.4.1 From e2664c1b00e24158c3e9cee02ab517935be2f8c9 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Fri, 22 Jul 2011 23:17:16 +0200 Subject: Added server sided automatic demo recording --- src/engine/client/client.cpp | 180 +-------------------------------- src/engine/client/client.h | 30 ------ src/engine/server.h | 2 + src/engine/server/server.cpp | 20 ++++ src/engine/server/server.h | 2 + src/engine/shared/config_variables.h | 2 + src/engine/shared/filecollection.cpp | 186 +++++++++++++++++++++++++++++++++++ src/engine/shared/filecollection.h | 35 +++++++ src/game/server/gamecontroller.cpp | 1 + 9 files changed, 249 insertions(+), 209 deletions(-) create mode 100644 src/engine/shared/filecollection.cpp create mode 100644 src/engine/shared/filecollection.h diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 37fda6c2..5029fe1e 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -231,185 +232,6 @@ void CSmoothTime::Update(CGraph *pGraph, int64 Target, int TimeLeft, int AdjustD } -bool CFileCollection::IsFilenameValid(const char *pFilename) -{ - if(str_length(pFilename) != m_FileDescLength+TIMESTAMP_LENGTH+m_FileExtLength || - str_comp_num(pFilename, m_aFileDesc, m_FileDescLength) || - str_comp(pFilename+m_FileDescLength+TIMESTAMP_LENGTH, m_aFileExt)) - return false; - - pFilename += m_FileDescLength; - if(pFilename[0] == '_' && - pFilename[1] >= '0' && pFilename[1] <= '9' && - pFilename[2] >= '0' && pFilename[2] <= '9' && - pFilename[3] >= '0' && pFilename[3] <= '9' && - pFilename[4] >= '0' && pFilename[4] <= '9' && - pFilename[5] == '-' && - pFilename[6] >= '0' && pFilename[6] <= '9' && - pFilename[7] >= '0' && pFilename[7] <= '9' && - pFilename[8] == '-' && - pFilename[9] >= '0' && pFilename[9] <= '9' && - pFilename[10] >= '0' && pFilename[10] <= '9' && - pFilename[11] == '_' && - pFilename[12] >= '0' && pFilename[12] <= '9' && - pFilename[13] >= '0' && pFilename[13] <= '9' && - pFilename[14] == '-' && - pFilename[15] >= '0' && pFilename[15] <= '9' && - pFilename[16] >= '0' && pFilename[16] <= '9' && - pFilename[17] == '-' && - pFilename[18] >= '0' && pFilename[18] <= '9' && - pFilename[19] >= '0' && pFilename[19] <= '9') - return true; - - return false; -} - -int64 CFileCollection::ExtractTimestamp(const char *pTimestring) -{ - int64 Timestamp = pTimestring[0]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[1]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[2]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[3]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[5]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[6]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[8]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[9]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[11]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[12]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[14]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[15]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[17]-'0'; Timestamp <<= 4; - Timestamp += pTimestring[18]-'0'; - - return Timestamp; -} - -void CFileCollection::BuildTimestring(int64 Timestamp, char *pTimestring) -{ - pTimestring[19] = 0; - pTimestring[18] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[17] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[16] = '-'; - pTimestring[15] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[14] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[13] = '-'; - pTimestring[12] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[11] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[10] = '_'; - pTimestring[9] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[8] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[7] = '-'; - pTimestring[6] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[5] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[4] = '-'; - pTimestring[3] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[2] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[1] = (Timestamp&0xF)+'0'; Timestamp >>= 4; - pTimestring[0] = (Timestamp&0xF)+'0'; -} - -void CFileCollection::Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries) -{ - mem_zero(m_aTimestamps, sizeof(m_aTimestamps)); - m_NumTimestamps = 0; - m_MaxEntries = clamp(MaxEntries, 1, static_cast(MAX_ENTRIES)); - str_copy(m_aFileDesc, pFileDesc, sizeof(m_aFileDesc)); - m_FileDescLength = str_length(m_aFileDesc); - str_copy(m_aFileExt, pFileExt, sizeof(m_aFileExt)); - m_FileExtLength = str_length(m_aFileExt); - str_copy(m_aPath, pPath, sizeof(m_aPath)); - m_pStorage = pStorage; - - m_pStorage->ListDirectory(IStorage::TYPE_SAVE, m_aPath, FilelistCallback, this); -} - -void CFileCollection::AddEntry(int64 Timestamp) -{ - if(m_NumTimestamps == 0) - { - // empty list - m_aTimestamps[m_NumTimestamps++] = Timestamp; - } - else - { - // remove old file - if(m_NumTimestamps == m_MaxEntries) - { - char aBuf[512]; - char aTimestring[TIMESTAMP_LENGTH]; - BuildTimestring(m_aTimestamps[0], aTimestring); - str_format(aBuf, sizeof(aBuf), "%s/%s_%s%s", m_aPath, m_aFileDesc, aTimestring, m_aFileExt); - m_pStorage->RemoveFile(aBuf, IStorage::TYPE_SAVE); - } - - // add entry to the sorted list - if(m_aTimestamps[0] > Timestamp) - { - // first entry - if(m_NumTimestamps < m_MaxEntries) - { - mem_move(m_aTimestamps+1, m_aTimestamps, m_NumTimestamps*sizeof(int64)); - m_aTimestamps[0] = Timestamp; - ++m_NumTimestamps; - } - } - else if(m_aTimestamps[m_NumTimestamps-1] <= Timestamp) - { - // last entry - if(m_NumTimestamps == m_MaxEntries) - { - mem_move(m_aTimestamps, m_aTimestamps+1, (m_NumTimestamps-1)*sizeof(int64)); - m_aTimestamps[m_NumTimestamps-1] = Timestamp; - } - else - m_aTimestamps[m_NumTimestamps++] = Timestamp; - } - else - { - // middle entry - int Left = 0, Right = m_NumTimestamps-1; - while(Right-Left > 1) - { - int Mid = (Left+Right)/2; - if(m_aTimestamps[Mid] > Timestamp) - Right = Mid; - else - Left = Mid; - } - - if(m_NumTimestamps == m_MaxEntries) - { - mem_move(m_aTimestamps, m_aTimestamps+1, (Right-1)*sizeof(int64)); - m_aTimestamps[Right-1] = Timestamp; - } - else - { - mem_move(m_aTimestamps+Right+1, m_aTimestamps+Right, (m_NumTimestamps-Right)*sizeof(int64)); - m_aTimestamps[Right] = Timestamp; - ++m_NumTimestamps; - } - } - } -} - -int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser) -{ - CFileCollection *pThis = static_cast(pUser); - - // check for valid file name format - if(IsDir || !pThis->IsFilenameValid(pFilename)) - return 0; - - // extract the timestamp - int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1); - - // add the entry - pThis->AddEntry(Timestamp); - - return 0; -} - - CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotDelta) { m_pEditor = 0; diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 3d81f073..1504a4e4 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -51,36 +51,6 @@ public: }; -class CFileCollection -{ - enum - { - MAX_ENTRIES=1000, - TIMESTAMP_LENGTH=20, // _YYYY-MM-DD_HH-MM-SS - }; - - int64 m_aTimestamps[MAX_ENTRIES]; - int m_NumTimestamps; - int m_MaxEntries; - char m_aFileDesc[128]; - int m_FileDescLength; - char m_aFileExt[32]; - int m_FileExtLength; - char m_aPath[512]; - IStorage *m_pStorage; - - bool IsFilenameValid(const char *pFilename); - int64 ExtractTimestamp(const char *pTimestring); - void BuildTimestring(int64 Timestamp, char *pTimestring); - -public: - void Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries); - void AddEntry(int64 Timestamp); - - static int FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser); -}; - - class CClient : public IClient, public CDemoPlayer::IListner { // needed interfaces diff --git a/src/engine/server.h b/src/engine/server.h index 28a97ecc..31134ca9 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -56,6 +56,8 @@ public: virtual bool IsAuthed(int ClientID) = 0; virtual void Kick(int ClientID, const char *pReason) = 0; + + virtual void DemoRecorder_HandleAutoStart() = 0; }; class IGameServer : public IInterface diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 46f87840..57be060b 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -1519,6 +1520,25 @@ void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser) ((CServer *)pUser)->m_RunServer = 0; } +void CServer::DemoRecorder_HandleAutoStart() +{ + if(g_Config.m_SvAutoDemoRecord) + { + m_DemoRecorder.Stop(); + char aFilename[128]; + char aDate[20]; + str_timestamp(aDate, sizeof(aDate)); + str_format(aFilename, sizeof(aFilename), "demos/%s_%s.demo", "auto/autorecord", aDate); + m_DemoRecorder.Start(Storage(), m_pConsole, aFilename, GameServer()->NetVersion(), m_aCurrentMap, m_CurrentMapCrc, "server"); + if(g_Config.m_SvAutoDemoMax) + { + // clean up auto recorded demos + CFileCollection AutoDemos; + AutoDemos.Init(Storage(), "demos/server", "autorecord", ".demo", g_Config.m_SvAutoDemoMax); + } + } +} + 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 4e575055..d8fdd8fa 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -148,6 +148,8 @@ public: void Kick(int ClientID, const char *pReason); + void DemoRecorder_HandleAutoStart(); + //int Tick() int64 TickStartTime(int Tick); //int TickSpeed() diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index cb8f5f15..0789476e 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -86,6 +86,8 @@ MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remo MACRO_CONFIG_STR(SvRconModPassword, sv_rcon_mod_password, 32, "", CFGFLAG_SERVER, "Remote console password for moderators (limited access)") MACRO_CONFIG_INT(SvRconMaxTries, sv_rcon_max_tries, 3, 0, 100, CFGFLAG_SERVER, "Maximum number of tries for remote console authentication") MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if remote console authentication fails. 0 makes it just use kick") +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") diff --git a/src/engine/shared/filecollection.cpp b/src/engine/shared/filecollection.cpp new file mode 100644 index 00000000..c7db92a6 --- /dev/null +++ b/src/engine/shared/filecollection.cpp @@ -0,0 +1,186 @@ +/* (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 "filecollection.h" + +bool CFileCollection::IsFilenameValid(const char *pFilename) +{ + if(str_length(pFilename) != m_FileDescLength+TIMESTAMP_LENGTH+m_FileExtLength || + str_comp_num(pFilename, m_aFileDesc, m_FileDescLength) || + str_comp(pFilename+m_FileDescLength+TIMESTAMP_LENGTH, m_aFileExt)) + return false; + + pFilename += m_FileDescLength; + if(pFilename[0] == '_' && + pFilename[1] >= '0' && pFilename[1] <= '9' && + pFilename[2] >= '0' && pFilename[2] <= '9' && + pFilename[3] >= '0' && pFilename[3] <= '9' && + pFilename[4] >= '0' && pFilename[4] <= '9' && + pFilename[5] == '-' && + pFilename[6] >= '0' && pFilename[6] <= '9' && + pFilename[7] >= '0' && pFilename[7] <= '9' && + pFilename[8] == '-' && + pFilename[9] >= '0' && pFilename[9] <= '9' && + pFilename[10] >= '0' && pFilename[10] <= '9' && + pFilename[11] == '_' && + pFilename[12] >= '0' && pFilename[12] <= '9' && + pFilename[13] >= '0' && pFilename[13] <= '9' && + pFilename[14] == '-' && + pFilename[15] >= '0' && pFilename[15] <= '9' && + pFilename[16] >= '0' && pFilename[16] <= '9' && + pFilename[17] == '-' && + pFilename[18] >= '0' && pFilename[18] <= '9' && + pFilename[19] >= '0' && pFilename[19] <= '9') + return true; + + return false; +} + +int64 CFileCollection::ExtractTimestamp(const char *pTimestring) +{ + int64 Timestamp = pTimestring[0]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[1]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[2]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[3]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[5]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[6]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[8]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[9]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[11]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[12]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[14]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[15]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[17]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[18]-'0'; + + return Timestamp; +} + +void CFileCollection::BuildTimestring(int64 Timestamp, char *pTimestring) +{ + pTimestring[19] = 0; + pTimestring[18] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[17] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[16] = '-'; + pTimestring[15] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[14] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[13] = '-'; + pTimestring[12] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[11] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[10] = '_'; + pTimestring[9] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[8] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[7] = '-'; + pTimestring[6] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[5] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[4] = '-'; + pTimestring[3] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[2] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[1] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[0] = (Timestamp&0xF)+'0'; +} + +void CFileCollection::Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries) +{ + mem_zero(m_aTimestamps, sizeof(m_aTimestamps)); + m_NumTimestamps = 0; + m_MaxEntries = clamp(MaxEntries, 1, static_cast(MAX_ENTRIES)); + str_copy(m_aFileDesc, pFileDesc, sizeof(m_aFileDesc)); + m_FileDescLength = str_length(m_aFileDesc); + str_copy(m_aFileExt, pFileExt, sizeof(m_aFileExt)); + m_FileExtLength = str_length(m_aFileExt); + str_copy(m_aPath, pPath, sizeof(m_aPath)); + m_pStorage = pStorage; + + m_pStorage->ListDirectory(IStorage::TYPE_SAVE, m_aPath, FilelistCallback, this); +} + +void CFileCollection::AddEntry(int64 Timestamp) +{ + if(m_NumTimestamps == 0) + { + // empty list + m_aTimestamps[m_NumTimestamps++] = Timestamp; + } + else + { + // remove old file + if(m_NumTimestamps == m_MaxEntries) + { + char aBuf[512]; + char aTimestring[TIMESTAMP_LENGTH]; + BuildTimestring(m_aTimestamps[0], aTimestring); + str_format(aBuf, sizeof(aBuf), "%s/%s_%s%s", m_aPath, m_aFileDesc, aTimestring, m_aFileExt); + m_pStorage->RemoveFile(aBuf, IStorage::TYPE_SAVE); + } + + // add entry to the sorted list + if(m_aTimestamps[0] > Timestamp) + { + // first entry + if(m_NumTimestamps < m_MaxEntries) + { + mem_move(m_aTimestamps+1, m_aTimestamps, m_NumTimestamps*sizeof(int64)); + m_aTimestamps[0] = Timestamp; + ++m_NumTimestamps; + } + } + else if(m_aTimestamps[m_NumTimestamps-1] <= Timestamp) + { + // last entry + if(m_NumTimestamps == m_MaxEntries) + { + mem_move(m_aTimestamps, m_aTimestamps+1, (m_NumTimestamps-1)*sizeof(int64)); + m_aTimestamps[m_NumTimestamps-1] = Timestamp; + } + else + m_aTimestamps[m_NumTimestamps++] = Timestamp; + } + else + { + // middle entry + int Left = 0, Right = m_NumTimestamps-1; + while(Right-Left > 1) + { + int Mid = (Left+Right)/2; + if(m_aTimestamps[Mid] > Timestamp) + Right = Mid; + else + Left = Mid; + } + + if(m_NumTimestamps == m_MaxEntries) + { + mem_move(m_aTimestamps, m_aTimestamps+1, (Right-1)*sizeof(int64)); + m_aTimestamps[Right-1] = Timestamp; + } + else + { + mem_move(m_aTimestamps+Right+1, m_aTimestamps+Right, (m_NumTimestamps-Right)*sizeof(int64)); + m_aTimestamps[Right] = Timestamp; + ++m_NumTimestamps; + } + } + } +} + +int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser) +{ + CFileCollection *pThis = static_cast(pUser); + + // check for valid file name format + if(IsDir || !pThis->IsFilenameValid(pFilename)) + return 0; + + // extract the timestamp + int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1); + + // add the entry + pThis->AddEntry(Timestamp); + + return 0; +} \ No newline at end of file diff --git a/src/engine/shared/filecollection.h b/src/engine/shared/filecollection.h new file mode 100644 index 00000000..c7548a8b --- /dev/null +++ b/src/engine/shared/filecollection.h @@ -0,0 +1,35 @@ +/* (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. */ +#ifndef ENGINE_SHARED_FILECOLLECTION_H +#define ENGINE_SHARED_FILECOLLECTION_H + +class CFileCollection +{ + enum + { + MAX_ENTRIES=1000, + TIMESTAMP_LENGTH=20, // _YYYY-MM-DD_HH-MM-SS + }; + + int64 m_aTimestamps[MAX_ENTRIES]; + int m_NumTimestamps; + int m_MaxEntries; + char m_aFileDesc[128]; + int m_FileDescLength; + char m_aFileExt[32]; + int m_FileExtLength; + char m_aPath[512]; + IStorage *m_pStorage; + + bool IsFilenameValid(const char *pFilename); + int64 ExtractTimestamp(const char *pTimestring); + void BuildTimestring(int64 Timestamp, char *pTimestring); + +public: + void Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries); + void AddEntry(int64 Timestamp); + + static int FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser); +}; + +#endif \ No newline at end of file diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index fd574d85..f8d418c3 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -217,6 +217,7 @@ void IGameController::StartRound() m_aTeamscore[TEAM_RED] = 0; m_aTeamscore[TEAM_BLUE] = 0; m_ForceBalanced = false; + Server()->DemoRecorder_HandleAutoStart(); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS); GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); -- cgit 1.4.1 From 94bdd95957af0f66da06275df2bcd041a75a3014 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 18:29:40 +0200 Subject: added missing newlines at end of 2 files --- src/engine/client/client.cpp | 2 +- src/engine/server/server.cpp | 3 +-- src/engine/shared/filecollection.cpp | 2 +- src/engine/shared/filecollection.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 5029fe1e..3d1a5a23 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -26,13 +26,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 57be060b..55208caa 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1,7 +1,6 @@ /* (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 @@ -17,12 +16,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include diff --git a/src/engine/shared/filecollection.cpp b/src/engine/shared/filecollection.cpp index c7db92a6..622534f2 100644 --- a/src/engine/shared/filecollection.cpp +++ b/src/engine/shared/filecollection.cpp @@ -183,4 +183,4 @@ int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int Stor pThis->AddEntry(Timestamp); return 0; -} \ No newline at end of file +} diff --git a/src/engine/shared/filecollection.h b/src/engine/shared/filecollection.h index c7548a8b..ac633892 100644 --- a/src/engine/shared/filecollection.h +++ b/src/engine/shared/filecollection.h @@ -32,4 +32,4 @@ public: static int FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser); }; -#endif \ No newline at end of file +#endif -- cgit 1.4.1 From f6301181ddfe56e50ea4dc5040035d19f9fedd2f Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 19:20:51 +0200 Subject: added Belarusian translation by arionwt1997 --- data/languages/belarusian.txt | 679 ++++++++++++++++++++++++++++++++++++++++++ data/languages/index.txt | 4 + 2 files changed, 683 insertions(+) create mode 100644 data/languages/belarusian.txt diff --git a/data/languages/belarusian.txt b/data/languages/belarusian.txt new file mode 100644 index 00000000..672995c0 --- /dev/null +++ b/data/languages/belarusian.txt @@ -0,0 +1,679 @@ + +##### translated strings ##### + +%d Bytes +== %d байт + +%d of %d servers, %d players +== %d з %d сервераў, %d гульцоў + +%d%% loaded +== %d%% загружана + +%ds left +== засталося %d сек. + +%i minute left +== Засталася %i хвіліна! + +%i minutes left +== Засталося %i хвілін! + +%i second left +== Засталася %i секунда! + +%i seconds left +== Засталося %i секунд! + +%s wins! +== %s перамог! + +-Page %d- +== -Старонка %d- + +Abort +== Адмена + +Add +== Дадаць + +Add Friend +== Дадаць сябра + +Address +== Адрас + +All +== Усё + +Alpha +== Празрыст. + +Always show name plates +== Заўсёды паказваць нікі гульцоў + +Are you sure that you want to delete the demo? +== Вы ўпэўнены, што жадаеце выдаліць дэма? + +Are you sure that you want to quit? +== Вы сапраўды жадаеце выйсці? + +Are you sure that you want to remove the player from your friends list? +== Вы ўпэўнены, што жадаеце выдаліць гульца з сяброў? + +As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. +== Бо гэта ваш першы запуск гульні, калі ласка, увядзіце свой нік у поле ніжэй. Таксама рекоммендуется праверыць налады гульні і памяняць некаторыя з іх перад тым, як пачаць гуляць. + +Automatically record demos +== Аўтаматычна запісваць дэма + +Automatically take game over screenshot +== Рабіць здымак вынікаў гульні + +Blue team +== Сінія + +Blue team wins! +== Сінія перамаглі! + +Body +== Цела + +Call vote +== Галасаваць + +Change settings +== Змяніць налады + +Chat +== Чат + +Clan +== Клан + +Client +== Кліент + +Close +== Выйсці + +Compatible version +== Сумяшчальная версія + +Connect +== Падлучыцца + +Connecting to +== Падлучэнне да + +Connection Problems... +== Праблемы з сувяззю... + +Console +== Кансоль + +Controls +== Кіраванне + +Count players only +== Лічыць толькі гульцоў + +Country +== Сцяг вашай краіны + +Crc: +== Crc: + +Created: +== Створаны: + +Current +== Бягучы + +Current version: %s +== Бягучая версія: %s + +Custom colors +== Свае колеры + +Delete +== Выдаліць + +Delete demo +== Выдаліць дэма + +Demo details +== Дэталі дэма + +Demofile: %s +== Дэма: %s + +Demos +== Дэма + +Disconnect +== Адключыць + +Disconnected +== Адключана + +Display Modes +== Дазвол экрана + +Downloading map +== Спампоўка карты + +Draw! +== Нічыя! + +Dynamic Camera +== Дынамічная камера + +Emoticon +== Эмоцыі + +Enter +== Уваход + +Error +== Памылка + +Error loading demo +== памылка пры загрузцы дэма + +FSAA samples +== Сэмплаў FSAA + +Favorite +== Абраны + +Favorites +== Абраныя + +Feet +== Ногі + +Filter +== Фільтр + +Fire +== Стрэл + +Folder +== Тэчка + +Force vote +== Фарсіраваць + +Free-View +== Вольны агляд + +Friends +== Сябры + +Fullscreen +== Поўнаэкранны рэжым + +Game +== Гульня + +Game info +== Інфа пра гульню + +Game over +== Гульня скончана + +Game type +== Тып гульні + +Game types: +== Тып гульні: + +General +== Асноўныя + +Graphics +== Графіка + +Grenade +== Гранатамёт + +Hammer +== Молат + +Has people playing +== Не пусты сервер + +High Detail +== Высокая дэталізацыя + +Hook +== Крук + +Host address +== Адрас сервера + +Hue +== Адценне + +Info +== Інфа + +Internet +== Інтэрнэт + +Invalid Demo +== Недапушчальнае дэма + +Join blue +== За сініх + +Join game +== Гуляць + +Join red +== За чырвоных + +Jump +== Скачок + +Kick player +== Забаніць гульца + +LAN +== LAN + +Language +== Мова + +Length: +== Даўжыня + +Lht. +== Яркасць + +Loading +== Загрузка + +MOTD +== MOTD + +Map +== Карта + +Map: +== Карта: + +Max Screenshots +== Максімальная колькасць здымкаў + +Max demos +== Максімальная колькасць дэма + +Maximum ping: +== Макс. пінг: + +Miscellaneous +== Дадаткова + +Mouse sens. +== Адчув. мышы + +Move left +== Крок налева + +Move player to spectators +== Зрабіць назіральнікам + +Move right +== Крок направа + +Movement +== Перасоўванне + +Mute when not active +== Глушыць гукі, калі гульня неактыўная + +Name +== Імя + +Name plates size +== Памер + +Netversion: +== Версія: + +New name: +== Новае імя + +News +== Навіны + +Next weapon +== След. зброя + +Nickname +== Нік + +No +== Не + +No password +== Без пароля + +No servers found +== Сервера не знойдзены + +No servers match your filter criteria +== Няма сервераў, падыходных пад ваш фільтр + +Ok +== ОК + +Open +== Адкрыць + +Parent Folder +== Бацькоўскі каталог + +Password +== Пароль + +Password incorrect +== Пароль + +Ping +== Пінг + +Pistol +== Пісталет + +Play +== Прагляд + +Play background music +== Гуляць фонавую музыку + +Player +== Гулец + +Player country: +== Краіна: + +Player options +== Опцыі гульца + +Players +== Гульцы + +Please balance teams! +== Збалансуйце каманды! + +Prev. weapon +== Прад. зброя + +Quality Textures +== Якасныя тэкстуры + +Quick search: +== Хуткі пошук: + +Quit +== Выйсце + +Quit anyway? +== Выйсці? + +REC %3d:%02d +== REC %3d:%02d + +Reason: +== Чыннік: + +Record demo +== Запісаць дэма + +Red team +== Чырвоныя + +Red team wins! +== Чырвоныя перамаглі! + +Refresh +== Абнавіць + +Refreshing master servers +== Абнаўленне спісу майстар-сервераў + +Remote console +== Кансоль сервера + +Remove +== Выдаліць + +Remove friend +== Выдаліць сябра + +Rename +== Пераназв. + +Rename demo +== Пераназваць дэма + +Reset filter +== Скінуць фільтры + +Reset to defaults +== Скінуць налады + +Rifle +== Бласцер + +Round +== Раўнд + +Sample rate +== Чашчыня + +Sat. +== Кантраст + +Score +== Ачкі + +Score board +== Табло + +Score limit +== Ліміт ачкоў + +Scoreboard +== Табло + +Screenshot +== Здымак + +Server address: +== Адрас сервера + +Server details +== Дэталі сервера + +Server filter +== Фільтр сервераў + +Server info +== Інфармацыя + +Server not full +== Сервер не запоўнены + +Settings +== Налады + +Shotgun +== Драбавік + +Show chat +== Паказаць чат + +Show friends only +== Толькі з сябрамі + +Show ingame HUD +== Паказваць нутрагульнявы HUD + +Show name plates +== Паказваць нікі гульцоў + +Show only supported +== Паказваць толькі падтрымоўваныя дазволы экрана + +Size: +== Памер: + +Skins +== Скіны + +Sound +== Гук + +Sound error +== Гукавая памылка + +Sound volume +== Гучнасць + +Spectate +== Назіраць + +Spectate next +== Назіраць наст. + +Spectate previous +== Назіраць папяр. + +Spectator mode +== Назіральнік + +Spectators +== Назіральнікі + +Standard gametype +== Стандартны тып гульні + +Standard map +== Стандартная карта + +Stop record +== Стоп + +Strict gametype filter +== Строгі фільтр рэжым. + +Sudden Death +== Хуткая смерць + +Switch weapon on pickup +== Перамыкаць зброю пры падборы + +Team +== Каманда + +Team chat +== Камандны чат + +Teeworlds %s is out! Download it at www.teeworlds.com! +== Выйшла Teeworlds %s! Спампоўвайце на www.teeworlds.com! + +Texture Compression +== Сціск тэкстур + +The audio device couldn't be initialised. +== Аўдыё прылада не можа быць ініцыялізавана + +The server is running a non-standard tuning on a pure game type. +== Сервер запушчаны з нестандартнымі наладамі на стандартным тыпе гульні. + +There's an unsaved map in the editor, you might want to save it before you quit the game. +== Ёсць незахаваная карта ў рэдактары, Вы можаце захаваць яе перад тым, як выйсці. + +Time limit +== Ліміт часу + +Time limit: %d min +== Ліміт часу: %d + +Try again +== ОК + +Type +== Тып + +Type: +== Тып: + +UI Color +== Колер інтэрфейсу + +Unable to delete the demo +== Немагчыма выдаліць дэма + +Unable to rename the demo +== Немагчыма пераназваць дэма + +Use sounds +== Выкарыстоўваць гукі + +Use team colors for name plates +== Камандныя колеры для нікаў гульцоў + +V-Sync +== Вертыкальная сінхранізацыя + +Version +== Версія + +Version: +== Версія: + +Vote command: +== Камманда галасавання: + +Vote description: +== Апісанне галасавання: + +Vote no +== Супраць + +Vote yes +== За + +Voting +== Галасаванне + +Warmup +== Размінка + +Weapon +== Зброя + +Welcome to Teeworlds +== Сардэчна запрашаем у Teeworlds! + +Yes +== Так + +You must restart the game for all settings to take effect. +== Перазапусціце гульню для ўжывання змен. + +Your skin +== Ваш скін + +no limit +== Без ліміту + +##### needs translation ##### + +##### old translations ##### + diff --git a/data/languages/index.txt b/data/languages/index.txt index 3a0c3a34..0d8e0901 100644 --- a/data/languages/index.txt +++ b/data/languages/index.txt @@ -1,6 +1,10 @@ ##### language indices ##### +belarusian +== Беларуская +== 112 + bosnian == Bosanski == 70 -- cgit 1.4.1 From 5c73b6afc8c726b32740ec8d1a4a2b1f48ec21b8 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 19:47:01 +0200 Subject: added Hungarian translation by Feca --- data/languages/hungarian.txt | 679 +++++++++++++++++++++++++++++++++++++++++++ data/languages/index.txt | 4 + 2 files changed, 683 insertions(+) create mode 100644 data/languages/hungarian.txt diff --git a/data/languages/hungarian.txt b/data/languages/hungarian.txt new file mode 100644 index 00000000..49f3116a --- /dev/null +++ b/data/languages/hungarian.txt @@ -0,0 +1,679 @@ + +##### translated strings ##### + +%d Bytes +== %d Bit + +%d of %d servers, %d players +== %d Szerver, %d Játékos + +%d%% loaded +== %d%% betöltve + +%ds left +== %ds vissza + +%i minute left +== %i perc vissza + +%i minutes left +== %i perc vissza + +%i second left +== %i másodperc vissza + +%i seconds left +== %i másodperc vissza + +%s wins! +== %s nyert! + +-Page %d- +== -oldal %d- + +Abort +== Mégse + +Add +== Hozzáad + +Add Friend +== Hozzáad barátot + +Address +== Cím + +All +== Mindenki + +Alpha +== Alpha + +Always show name plates +== Mindig mutassa a névtáblát + +Are you sure that you want to delete the demo? +== Biztos hogy le akarod törölni a demót? + +Are you sure that you want to quit? +== Biztos hogy ki akarsz lépni? + +Are you sure that you want to remove the player from your friends list? +== Biztos vagy benne hogy ki akarod törölni a játékost a barátok listájáról? + +As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. +== Mivel ez az első alkalom hogy elindítottad ezt a játékot, kérlekk add meg a neved! + +Automatically record demos +== Magától rögzítse a demókat + +Automatically take game over screenshot +== Magától készítsen a játék végén képet + +Blue team +== Kék csapat + +Blue team wins! +== A kék csapat nyert! + +Body +== Test + +Call vote +== Szavazás + +Change settings +== Beállítások átállítása + +Chat +== Chat + +Clan +== Klán + +Client +== Kliens + +Close +== Bezárás + +Compatible version +== Kompatibilis Verzió + +Connect +== Csatlakozás + +Connecting to +== Csatlakozás a + +Connection Problems... +== Csatlakozási problémák... + +Console +== Konzol + +Controls +== Irányítás + +Count players only +== Csak számontartott játékosok + +Country +== Ország + +Crc: +== Crc: + +Created: +== Készítette: + +Current +== Aktuális + +Current version: %s +== Aktuális verzió: %s + +Custom colors +== Egyéni színek + +Delete +== Törlés + +Delete demo +== Demó törlése + +Demo details +== Információk a demóról + +Demos +== Demók + +Disconnect +== Szerver elhagyása + +Disconnected +== Kilépett + +Display Modes +== Kijelző módok + +Downloading map +== Pálya letöltése + +Draw! +== Rajzolj! + +Dynamic Camera +== Dinamikus kamera + +Emoticon +== Hangulatjel + +Enter +== Belépés + +Error +== Hiba + +Error loading demo +== Hiba a demó betöltésében + +FSAA samples +== FSAA mintáku + +Favorite +== Kedvenc + +Favorites +== Kedvencek + +Feet +== Láb + +Filter +== Szűrő + +Fire +== Tűz + +Folder +== Mappa + +Force vote +== Különleges szavazás + +Free-View +== Szabad-nézet + +Friends +== Barátok + +Fullscreen +== Teljesképernyő + +Game +== Játék + +Game info +== Játék infó + +Game over +== Játék vége + +Game type +== Játék fajtája + +Game types: +== Játék fajtái: + +General +== Általános + +Graphics +== Grafika + +Grenade +== Gránát + +Hammer +== Kalapács + +Has people playing +== Játékos játszik + +High Detail +== Jó részletek + +Hook +== Horog + +Host address +== Szerver címe + +Hue +== Színárnyalat + +Info +== Infó + +Internet +== Internet + +Invalid Demo +== Érvénytelen demó + +Join blue +== Kékhez lépés + +Join game +== Csatlakozás a játékhoz + +Join red +== Piroshoz lépés + +Jump +== Ugrás + +Kick player +== Játékos kirúgása + +LAN +== Helyi + +Language +== Nyelv + +Length: +== Hossza: + +Lht. +== Lht. + +Loading +== Betöltés + +MOTD +== Napi üzenet + +Map +== Pálya + +Map: +== Pálya: + +Max Screenshots +== Maximum Fotó + +Max demos +== Maximum Demó + +Maximum ping: +== Maximum Ping: + +Miscellaneous +== Vegyes + +Mouse sens. +== Egér érzékenysége + +Move left +== Balra lépés + +Move player to spectators +== Megfigyelő lett + +Move right +== Jobbra lépés + +Movement +== Mozgás + +Mute when not active +== Letiltás ha nem aktív + +Name +== Név + +Name plates size +== Névtáblák mérete + +Netversion: +== Netes verzió: + +New name: +== Új Név: + +News +== Hírek + +Next weapon +== Következő fegyver + +Nickname +== Becenév + +No +== Nem + +No password +== Jelszó nélküli + +No servers found +== Nem talált szervereket + +No servers match your filter criteria +== Nincs szerver a szűrőfeltételeidhez + +Ok +== Oké + +Open +== Megnyit + +Parent Folder +== Szülői mappa + +Password +== Jelszó + +Password incorrect +== Helytelen jelszó + +Ping +== Ping + +Pistol +== Pisztoly + +Play +== Játék + +Player +== Játékos + +Player options +== Játékos beállításai + +Players +== Játékosok + +Please balance teams! +== Kérlek egyenlítsd ki a csapatokat! + +Prev. weapon +== Előző fegyver + +Quality Textures +== Minőségi kidolgozás + +Quick search: +== Gyors keresés: + +Quit +== Kilépés + +Quit anyway? +== Mindenképpen kilép? + +REC %3d:%02d +== REC %3d:%02d + +Reason: +== Indok: + +Record demo +== Demó felvétele + +Red team +== Piros csapat + +Red team wins! +== A piros csapat nyert! + +Refresh +== Újratöltés + +Refreshing master servers +== A master szerverek frissítése + +Remote console +== Távoli konzol + +Remove +== Eltávolítás + +Remove friend +== Barát eltávolítása + +Rename +== Átnevezés + +Rename demo +== Demó átnevezése + +Reset filter +== Szűrő visszaállítása + +Reset to defaults +== Visszaállítás az alapértelmezettre + +Rifle +== Lézer + +Round +== Menet + +Sample rate +== Mintavételi frekvencia + +Sat. +== Sat. + +Score +== Pontszám + +Score board +== Pontszám tábla + +Score limit +== Ponthatár + +Scoreboard +== Pontszámtábla + +Screenshot +== Pillanatkép + +Server address: +== Szerver címe: + +Server details +== Szerver részletei + +Server filter +== Szerver szűrő + +Server info +== Szerver infó + +Server not full +== Szerver nincs tele + +Settings +== Beállítások + +Shotgun +== Sörétes puska + +Show chat +== Chat mutatása + +Show friends only +== Barátok mutatása + +Show ingame HUD +== Játék közbeni HUD mutatása + +Show name plates +== Név táblák mutatása + +Show only supported +== Csak támogatott mutatása + +Size: +== Méret: + +Skins +== Skinek + +Sound +== Hang + +Sound error +== Hang hiba + +Sound volume +== Hangerő + +Spectate +== Megfigyelés + +Spectator mode +== Néző mód + +Spectators +== Megfigyelők + +Standard gametype +== Általános játékfajta + +Standard map +== Általános pálya + +Stop record +== Felvétel megállítása + +Sudden Death +== Gyors halál + +Switch weapon on pickup +== Fegyverváltás felvételnél + +Team +== Csapat + +Team chat +== Csapat chat + +Teeworlds %s is out! Download it at www.teeworlds.com! +== Teeworlds %s kint van! Töltsd le www.teeworlds.com oldalon! + +Texture Compression +== Textúra tömörítés + +The audio device couldn't be initialised. +== A hangeszköz nem kezdeményezhető. + +The server is running a non-standard tuning on a pure game type. +== A szerver egy nem szabványos hangolást futtat a tiszta játék típuson. + +There's an unsaved map in the editor, you might want to save it before you quit the game. +== Van egy mentett térkép a szerkesztőben, talán akarod menteni, mielőtt kilépsz a játékból. + +Time limit +== Időhatár + +Time limit: %d min +== Időhatár: %d perc + +Try again +== Próbáld újra + +Type +== Típus + +Type: +== Típus: + +UI Color +== UI Szín + +Unable to delete the demo +== Nem sikerült törölni a demó + +Unable to rename the demo +== Nem sikerült átnevezni a demó + +Use sounds +== Hangok használata + +Use team colors for name plates +== Csapat szín használata név tábláknál + +V-Sync +== V-Sync + +Version +== Verzió + +Version: +== Verzió: + +Vote command: +== Szavazás parancsa: + +Vote description: +== Szavazás leírása: + +Vote no +== Nem + +Vote yes +== Igen + +Voting +== Szavazás + +Warmup +== Kezdés + +Weapon +== Fegyver + +Welcome to Teeworlds +== Üdvözöljük a Teeworlds-ben + +Yes +== Igen + +You must restart the game for all settings to take effect. +== Újra kell indítani a játékot, a beállítások érvénybe lépéséhez. + +Your skin +== Te skined + +no limit +== Nincs korlát + +##### needs translation ##### + +Demofile: %s +== + +Play background music +== + +Player country: +== + +Spectate next +== + +Spectate previous +== + +Strict gametype filter +== + +##### old translations ##### + diff --git a/data/languages/index.txt b/data/languages/index.txt index 0d8e0901..b7a6179b 100644 --- a/data/languages/index.txt +++ b/data/languages/index.txt @@ -41,6 +41,10 @@ german == Deutsch == 276 +hungarian +== Magyar +== 348 + italian == Italiano == 380 -- cgit 1.4.1 From 7e4449d05a07fe670f9f09daae5d7c94b9ce45f2 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 19:50:58 +0200 Subject: added fix for Ukrainian translation by 404_not_found --- data/languages/ukrainian.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data/languages/ukrainian.txt b/data/languages/ukrainian.txt index 9e696f51..93566829 100644 --- a/data/languages/ukrainian.txt +++ b/data/languages/ukrainian.txt @@ -50,7 +50,7 @@ Chat == Чат Close -== Закрити +== Зачинити Compatible version == Сумісна версія @@ -86,10 +86,10 @@ Demos == Демо Disconnect -== # Відключитись +== Від'єднатись Disconnected -== Відключено +== Від'єднанно Display Modes == Режими дисплея @@ -155,7 +155,7 @@ Game type == Тип гри Game types: -== Тип гри: +== Типи гри: General == Основні @@ -164,7 +164,7 @@ Graphics == Графіка Grenade -== Граната +== Ракетниця Hammer == Молоток @@ -215,7 +215,7 @@ Lht. == Яскравість Loading -== Завантиження +== Завантаження MOTD == MOTD @@ -245,7 +245,7 @@ Mute when not active == Глушити звуки, коли гра неактивна Name -== Імя +== Ім'я News == Новини @@ -332,7 +332,7 @@ Remote console == Консоль сервера Reset filter -== Сикнути фільтри +== Скинути фільтри Reset to defaults == Скинути налаштування -- cgit 1.4.1 From 9e5ead2fbdcb6e91fdb63e33935d68147eefa8b5 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 30 Jul 2011 22:30:26 +0200 Subject: fixed nethash --- scripts/cmd5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cmd5.py b/scripts/cmd5.py index 07e35bb1..9b4804c7 100644 --- a/scripts/cmd5.py +++ b/scripts/cmd5.py @@ -30,6 +30,6 @@ for filename in sys.argv[1:]: hash = hashlib.md5(f).hexdigest().lower()[16:] #TODO 0.7: improve nethash creation -if hash == "71de0f4d82688970": +if hash == "63d6e69c6025feff": hash = "626fce9a778df4d4" print('#define GAME_NETVERSION_HASH "%s"' % hash) -- cgit 1.4.1 From 34132ce2443f286fdfd36220fcd2ed53199e9199 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 01:38:45 +0200 Subject: fixed client crash in debug --- src/engine/client/friends.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/client/friends.cpp b/src/engine/client/friends.cpp index 99f82b50..eca39edb 100644 --- a/src/engine/client/friends.cpp +++ b/src/engine/client/friends.cpp @@ -12,6 +12,7 @@ CFriends::CFriends() { mem_zero(m_aFriends, sizeof(m_aFriends)); + m_NumFriends = 0; } void CFriends::ConAddFriend(IConsole::IResult *pResult, void *pUserData) -- cgit 1.4.1 From 8d0cc2a825b39b58d9a9dc3d884159fb9255fea2 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 01:40:28 +0200 Subject: reduced stack memory usage of CDataFileWriter --- src/engine/shared/datafile.cpp | 113 ++++++++++++++++++++++++----------------- src/engine/shared/datafile.h | 16 ++++-- 2 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/engine/shared/datafile.cpp b/src/engine/shared/datafile.cpp index 00410038..e2215635 100644 --- a/src/engine/shared/datafile.cpp +++ b/src/engine/shared/datafile.cpp @@ -422,6 +422,25 @@ unsigned CDataFileReader::Crc() return m_pDataFile->m_Crc; } + +CDataFileWriter::CDataFileWriter() +{ + m_File = 0; + m_pItemTypes = static_cast(mem_alloc(sizeof(CItemTypeInfo) * MAX_ITEM_TYPES, 1)); + m_pItems = static_cast(mem_alloc(sizeof(CItemInfo) * MAX_ITEMS, 1)); + m_pDatas = static_cast(mem_alloc(sizeof(CDataInfo) * MAX_DATAS, 1)); +} + +CDataFileWriter::~CDataFileWriter() +{ + mem_free(m_pItemTypes); + m_pItemTypes = 0; + mem_free(m_pItems); + m_pItems = 0; + mem_free(m_pDatas); + m_pDatas = 0; +} + bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename) { dbg_assert(!m_File, "a file already exists"); @@ -432,12 +451,12 @@ bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename) m_NumItems = 0; m_NumDatas = 0; m_NumItemTypes = 0; - mem_zero(&m_aItemTypes, sizeof(m_aItemTypes)); + mem_zero(m_pItemTypes, sizeof(CItemTypeInfo) * MAX_ITEM_TYPES); - for(int i = 0; i < 0xffff; i++) + for(int i = 0; i < MAX_ITEM_TYPES; i++) { - m_aItemTypes[i].m_First = -1; - m_aItemTypes[i].m_Last = -1; + m_pItemTypes[i].m_First = -1; + m_pItemTypes[i].m_Last = -1; } return true; @@ -451,29 +470,29 @@ int CDataFileWriter::AddItem(int Type, int ID, int Size, void *pData) dbg_assert(m_NumItems < 1024, "too many items"); dbg_assert(Size%sizeof(int) == 0, "incorrect boundary"); - m_aItems[m_NumItems].m_Type = Type; - m_aItems[m_NumItems].m_ID = ID; - m_aItems[m_NumItems].m_Size = Size; + m_pItems[m_NumItems].m_Type = Type; + m_pItems[m_NumItems].m_ID = ID; + m_pItems[m_NumItems].m_Size = Size; // copy data - m_aItems[m_NumItems].m_pData = mem_alloc(Size, 1); - mem_copy(m_aItems[m_NumItems].m_pData, pData, Size); + m_pItems[m_NumItems].m_pData = mem_alloc(Size, 1); + mem_copy(m_pItems[m_NumItems].m_pData, pData, Size); - if(!m_aItemTypes[Type].m_Num) // count item types + if(!m_pItemTypes[Type].m_Num) // count item types m_NumItemTypes++; // link - m_aItems[m_NumItems].m_Prev = m_aItemTypes[Type].m_Last; - m_aItems[m_NumItems].m_Next = -1; + m_pItems[m_NumItems].m_Prev = m_pItemTypes[Type].m_Last; + m_pItems[m_NumItems].m_Next = -1; - if(m_aItemTypes[Type].m_Last != -1) - m_aItems[m_aItemTypes[Type].m_Last].m_Next = m_NumItems; - m_aItemTypes[Type].m_Last = m_NumItems; + if(m_pItemTypes[Type].m_Last != -1) + m_pItems[m_pItemTypes[Type].m_Last].m_Next = m_NumItems; + m_pItemTypes[Type].m_Last = m_NumItems; - if(m_aItemTypes[Type].m_First == -1) - m_aItemTypes[Type].m_First = m_NumItems; + if(m_pItemTypes[Type].m_First == -1) + m_pItemTypes[Type].m_First = m_NumItems; - m_aItemTypes[Type].m_Num++; + m_pItemTypes[Type].m_Num++; m_NumItems++; return m_NumItems-1; @@ -485,7 +504,7 @@ int CDataFileWriter::AddData(int Size, void *pData) dbg_assert(m_NumDatas < 1024, "too much data"); - CDataInfo *pInfo = &m_aDatas[m_NumDatas]; + CDataInfo *pInfo = &m_pDatas[m_NumDatas]; unsigned long s = compressBound(Size); void *pCompData = mem_alloc(s, 1); // temporary buffer that we use during compression @@ -540,13 +559,13 @@ int CDataFileWriter::Finish() for(int i = 0; i < m_NumItems; i++) { if(DEBUG) - dbg_msg("datafile", "item=%d size=%d (%d)", i, m_aItems[i].m_Size, m_aItems[i].m_Size+sizeof(CDatafileItem)); - ItemSize += m_aItems[i].m_Size + sizeof(CDatafileItem); + dbg_msg("datafile", "item=%d size=%d (%d)", i, m_pItems[i].m_Size, m_pItems[i].m_Size+sizeof(CDatafileItem)); + ItemSize += m_pItems[i].m_Size + sizeof(CDatafileItem); } for(int i = 0; i < m_NumDatas; i++) - DataSize += m_aDatas[i].m_CompressedSize; + DataSize += m_pDatas[i].m_CompressedSize; // calculate the complete size TypesSize = m_NumItemTypes*sizeof(CDatafileItemType); @@ -587,30 +606,30 @@ int CDataFileWriter::Finish() // write types for(int i = 0, Count = 0; i < 0xffff; i++) { - if(m_aItemTypes[i].m_Num) + if(m_pItemTypes[i].m_Num) { // write info CDatafileItemType Info; Info.m_Type = i; Info.m_Start = Count; - Info.m_Num = m_aItemTypes[i].m_Num; + Info.m_Num = m_pItemTypes[i].m_Num; if(DEBUG) dbg_msg("datafile", "writing type=%x start=%d num=%d", Info.m_Type, Info.m_Start, Info.m_Num); #if defined(CONF_ARCH_ENDIAN_BIG) swap_endian(&Info, sizeof(int), sizeof(CDatafileItemType)/sizeof(int)); #endif io_write(m_File, &Info, sizeof(Info)); - Count += m_aItemTypes[i].m_Num; + Count += m_pItemTypes[i].m_Num; } } // write item offsets for(int i = 0, Offset = 0; i < 0xffff; i++) { - if(m_aItemTypes[i].m_Num) + if(m_pItemTypes[i].m_Num) { - // write all m_aItems in of this type - int k = m_aItemTypes[i].m_First; + // write all m_pItems in of this type + int k = m_pItemTypes[i].m_First; while(k != -1) { if(DEBUG) @@ -620,10 +639,10 @@ int CDataFileWriter::Finish() swap_endian(&Temp, sizeof(int), sizeof(Temp)/sizeof(int)); #endif io_write(m_File, &Temp, sizeof(Temp)); - Offset += m_aItems[k].m_Size + sizeof(CDatafileItem); + Offset += m_pItems[k].m_Size + sizeof(CDatafileItem); // next - k = m_aItems[k].m_Next; + k = m_pItems[k].m_Next; } } } @@ -638,45 +657,45 @@ int CDataFileWriter::Finish() swap_endian(&Temp, sizeof(int), sizeof(Temp)/sizeof(int)); #endif io_write(m_File, &Temp, sizeof(Temp)); - Offset += m_aDatas[i].m_CompressedSize; + Offset += m_pDatas[i].m_CompressedSize; } // write data uncompressed sizes for(int i = 0; i < m_NumDatas; i++) { if(DEBUG) - dbg_msg("datafile", "writing data uncompressed size num=%d size=%d", i, m_aDatas[i].m_UncompressedSize); - int UncompressedSize = m_aDatas[i].m_UncompressedSize; + dbg_msg("datafile", "writing data uncompressed size num=%d size=%d", i, m_pDatas[i].m_UncompressedSize); + int UncompressedSize = m_pDatas[i].m_UncompressedSize; #if defined(CONF_ARCH_ENDIAN_BIG) swap_endian(&UncompressedSize, sizeof(int), sizeof(UncompressedSize)/sizeof(int)); #endif io_write(m_File, &UncompressedSize, sizeof(UncompressedSize)); } - // write m_aItems + // write m_pItems for(int i = 0; i < 0xffff; i++) { - if(m_aItemTypes[i].m_Num) + if(m_pItemTypes[i].m_Num) { - // write all m_aItems in of this type - int k = m_aItemTypes[i].m_First; + // write all m_pItems in of this type + int k = m_pItemTypes[i].m_First; while(k != -1) { CDatafileItem Item; - Item.m_TypeAndID = (i<<16)|m_aItems[k].m_ID; - Item.m_Size = m_aItems[k].m_Size; + Item.m_TypeAndID = (i<<16)|m_pItems[k].m_ID; + Item.m_Size = m_pItems[k].m_Size; if(DEBUG) - dbg_msg("datafile", "writing item type=%x idx=%d id=%d size=%d", i, k, m_aItems[k].m_ID, m_aItems[k].m_Size); + dbg_msg("datafile", "writing item type=%x idx=%d id=%d size=%d", i, k, m_pItems[k].m_ID, m_pItems[k].m_Size); #if defined(CONF_ARCH_ENDIAN_BIG) swap_endian(&Item, sizeof(int), sizeof(Item)/sizeof(int)); - swap_endian(m_aItems[k].m_pData, sizeof(int), m_aItems[k].m_Size/sizeof(int)); + swap_endian(m_pItems[k].m_pData, sizeof(int), m_pItems[k].m_Size/sizeof(int)); #endif io_write(m_File, &Item, sizeof(Item)); - io_write(m_File, m_aItems[k].m_pData, m_aItems[k].m_Size); + io_write(m_File, m_pItems[k].m_pData, m_pItems[k].m_Size); // next - k = m_aItems[k].m_Next; + k = m_pItems[k].m_Next; } } } @@ -685,15 +704,15 @@ int CDataFileWriter::Finish() for(int i = 0; i < m_NumDatas; i++) { if(DEBUG) - dbg_msg("datafile", "writing data id=%d size=%d", i, m_aDatas[i].m_CompressedSize); - io_write(m_File, m_aDatas[i].m_pCompressedData, m_aDatas[i].m_CompressedSize); + dbg_msg("datafile", "writing data id=%d size=%d", i, m_pDatas[i].m_CompressedSize); + io_write(m_File, m_pDatas[i].m_pCompressedData, m_pDatas[i].m_CompressedSize); } // free data for(int i = 0; i < m_NumItems; i++) - mem_free(m_aItems[i].m_pData); + mem_free(m_pItems[i].m_pData); for(int i = 0; i < m_NumDatas; ++i) - mem_free(m_aDatas[i].m_pCompressedData); + mem_free(m_pDatas[i].m_pCompressedData); io_close(m_File); m_File = 0; diff --git a/src/engine/shared/datafile.h b/src/engine/shared/datafile.h index 9f27f968..cafce20e 100644 --- a/src/engine/shared/datafile.h +++ b/src/engine/shared/datafile.h @@ -61,16 +61,24 @@ class CDataFileWriter int m_Last; }; + enum + { + MAX_ITEM_TYPES=0xffff, + MAX_ITEMS=1024, + MAX_DATAS=1024, + }; + IOHANDLE m_File; int m_NumItems; int m_NumDatas; int m_NumItemTypes; - CItemTypeInfo m_aItemTypes[0xffff]; - CItemInfo m_aItems[1024]; - CDataInfo m_aDatas[1024]; + CItemTypeInfo *m_pItemTypes; + CItemInfo *m_pItems; + CDataInfo *m_pDatas; public: - CDataFileWriter() : m_File(0) {} + CDataFileWriter(); + ~CDataFileWriter(); bool Open(class IStorage *pStorage, const char *Filename); int AddData(int Size, void *pData); int AddDataSwapped(int Size, void *pData); -- cgit 1.4.1 From 10c3e844d77996f6a383791edc673bd7855dd321 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 02:04:46 +0200 Subject: show alpha2 country code strings next to the flag in the country code selectors. Closes #805 --- src/game/client/components/countryflags.cpp | 1 + src/game/client/components/countryflags.h | 3 ++- src/game/client/components/menus.cpp | 5 ++++- src/game/client/components/menus_settings.cpp | 5 ++++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/game/client/components/countryflags.cpp b/src/game/client/components/countryflags.cpp index d6b30fe0..ef350cd7 100644 --- a/src/game/client/components/countryflags.cpp +++ b/src/game/client/components/countryflags.cpp @@ -69,6 +69,7 @@ void CCountryFlags::LoadCountryflagsIndexfile() // add entry CCountryFlag CountryFlag; CountryFlag.m_CountryCode = CountryCode; + str_copy(CountryFlag.m_aCountryCodeString, aOrigin, sizeof(CountryFlag.m_aCountryCodeString)); CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); mem_free(Info.m_pData); str_format(aBuf, sizeof(aBuf), "loaded country flag '%s'", aOrigin); diff --git a/src/game/client/components/countryflags.h b/src/game/client/components/countryflags.h index 15eb8598..ad24a762 100644 --- a/src/game/client/components/countryflags.h +++ b/src/game/client/components/countryflags.h @@ -12,9 +12,10 @@ public: struct CCountryFlag { int m_CountryCode; + char m_aCountryCodeString[8]; int m_Texture; - bool operator<(const CCountryFlag &Other) { return m_CountryCode < Other.m_CountryCode; } + bool operator<(const CCountryFlag &Other) { return str_comp(m_aCountryCodeString, Other.m_aCountryCodeString) < 0; } }; void OnInit(); diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 4f3d2da7..8f330f78 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1125,7 +1125,9 @@ int CMenus::Render() CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected == i); if(Item.m_Visible) { - Item.m_Rect.Margin(10.0f, &Item.m_Rect); + CUIRect Label; + Item.m_Rect.Margin(5.0f, &Item.m_Rect); + Item.m_Rect.HSplitBottom(10.0f, &Item.m_Rect, &Label); float OldWidth = Item.m_Rect.w; Item.m_Rect.w = Item.m_Rect.h*2; Item.m_Rect.x += (OldWidth-Item.m_Rect.w)/ 2.0f; @@ -1135,6 +1137,7 @@ int CMenus::Render() IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, Item.m_Rect.w, Item.m_Rect.h); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); + UI()->DoLabel(&Label, pEntry->m_aCountryCodeString, 10.0f, 0); } } diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index c2fab00f..51fdbd29 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -215,7 +215,9 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView) CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected == i); if(Item.m_Visible) { - Item.m_Rect.Margin(10.0f, &Item.m_Rect); + CUIRect Label; + Item.m_Rect.Margin(5.0f, &Item.m_Rect); + Item.m_Rect.HSplitBottom(10.0f, &Item.m_Rect, &Label); float OldWidth = Item.m_Rect.w; Item.m_Rect.w = Item.m_Rect.h*2; Item.m_Rect.x += (OldWidth-Item.m_Rect.w)/ 2.0f; @@ -225,6 +227,7 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView) IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, Item.m_Rect.w, Item.m_Rect.h); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); + UI()->DoLabel(&Label, pEntry->m_aCountryCodeString, 10.0f, 0); } } -- cgit 1.4.1 From 9349af008572efe573ec435cf70d02c2f5db9821 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 02:20:46 +0200 Subject: clean up econ sockets on shutdown. Closes #804 --- src/engine/server/server.cpp | 2 ++ src/engine/shared/econ.cpp | 8 ++++++++ src/engine/shared/econ.h | 1 + src/engine/shared/network_console.cpp | 9 ++++++++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 55208caa..2d288740 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1331,6 +1331,8 @@ int CServer::Run() { if(m_aClients[i].m_State != CClient::STATE_EMPTY) m_NetServer.Drop(i, "Server shutdown"); + + m_Econ.Shutdown(); } GameServer()->OnShutdown(); diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp index ba86e5c0..0bc3a988 100644 --- a/src/engine/shared/econ.cpp +++ b/src/engine/shared/econ.cpp @@ -145,3 +145,11 @@ void CEcon::Send(int ClientID, const char *pLine) else if(ClientID >= 0 && ClientID < NET_MAX_CONSOLE_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_AUTHED) m_NetConsole.Send(ClientID, pLine); } + +void CEcon::Shutdown() +{ + if(!m_Ready) + return; + + m_NetConsole.Close(); +} diff --git a/src/engine/shared/econ.h b/src/engine/shared/econ.h index 33b23ea6..3ec19e28 100644 --- a/src/engine/shared/econ.h +++ b/src/engine/shared/econ.h @@ -38,6 +38,7 @@ public: void Init(IConsole *pConsole); void Update(); void Send(int ClientID, const char *pLine); + void Shutdown(); }; #endif diff --git a/src/engine/shared/network_console.cpp b/src/engine/shared/network_console.cpp index 0cf2a718..f77e40f2 100644 --- a/src/engine/shared/network_console.cpp +++ b/src/engine/shared/network_console.cpp @@ -7,6 +7,9 @@ bool CNetConsole::Open(NETADDR BindAddr, 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; // open socket m_Socket = net_tcp_create(BindAddr); @@ -31,7 +34,11 @@ void CNetConsole::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT int CNetConsole::Close() { - // TODO: implement me + for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) + m_aSlots[i].m_Connection.Disconnect("closing console"); + + net_tcp_close(m_Socket); + return 0; } -- cgit 1.4.1 From aabac3dcfce42ee1bf04cd4f428f7e52e9aa26b1 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 02:25:55 +0200 Subject: send notification to enter a password when a client connects to econ. Closes #803 --- src/engine/shared/econ.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp index 0bc3a988..18a551e7 100644 --- a/src/engine/shared/econ.cpp +++ b/src/engine/shared/econ.cpp @@ -16,6 +16,8 @@ int CEcon::NewClientCallback(int ClientID, void *pUser) pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTED; pThis->m_aClients[ClientID].m_TimeConnected = time_get(); + + pThis->m_NetConsole.Send(ClientID, "Enter password:"); return 0; } -- cgit 1.4.1 From 1705c90e148d680c4b8002d12ac15a7d228f6408 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 12:43:35 +0200 Subject: fixed ban for life on the server --- src/engine/server/server.cpp | 2 +- src/engine/shared/network_server.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 2d288740..65bb231a 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1364,7 +1364,7 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser) const char *pReason = "No reason given"; if(pResult->NumArguments() > 1) - Minutes = pResult->GetInteger(1); + Minutes = max(0, pResult->GetInteger(1)); if(pResult->NumArguments() > 2) pReason = pResult->GetString(2); diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index f3fbfa32..b100e1a2 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -221,10 +221,10 @@ int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason) char Buf[128]; NETADDR BanAddr; - int Mins = (Seconds + 59) / 60; - if(Mins) + if(Stamp > -1) { - if(Mins == 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); @@ -255,7 +255,7 @@ int CNetServer::Update() } // remove expired bans - while(m_BanPool_FirstUsed && m_BanPool_FirstUsed->m_Info.m_Expires < Now) + 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); @@ -307,10 +307,10 @@ int CNetServer::Recv(CNetChunk *pChunk) { // banned, reply with a message char BanStr[128]; - if(pBan->m_Info.m_Expires) + if(pBan->m_Info.m_Expires > -1) { int Mins = ((pBan->m_Info.m_Expires - Now)+59)/60; - if(Mins == 1) + 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); -- cgit 1.4.1 From 94188021509a376fc352b7707d9a324335a97eba Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 13:05:12 +0200 Subject: protected econ authentication against brute force --- src/engine/shared/config_variables.h | 1 + src/engine/shared/econ.cpp | 18 +++++++- src/engine/shared/econ.h | 6 +++ src/engine/shared/network.h | 18 +++++++- src/engine/shared/network_console.cpp | 87 ++++++++++++++++++++++++++++++++++- 5 files changed, 126 insertions(+), 4 deletions(-) diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 0789476e..c812063a 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -92,6 +92,7 @@ MACRO_CONFIG_INT(SvAutoDemoMax, sv_auto_demo_max, 10, 0, 1000, CFGFLAG_SERVER, " 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") diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp index 18a551e7..617cdbd6 100644 --- a/src/engine/shared/econ.cpp +++ b/src/engine/shared/econ.cpp @@ -16,6 +16,7 @@ int CEcon::NewClientCallback(int ClientID, void *pUser) pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTED; pThis->m_aClients[ClientID].m_TimeConnected = time_get(); + pThis->m_aClients[ClientID].m_AuthTries = 0; pThis->m_NetConsole.Send(ClientID, "Enter password:"); return 0; @@ -112,7 +113,22 @@ void CEcon::Update() Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "econ", aBuf); } else - m_NetConsole.Send(ClientID, "Wrong password"); + { + 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); + if(m_aClients[ClientID].m_AuthTries >= MAX_AUTH_TRIES) + { + 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); + } + } + } } else if(m_aClients[ClientID].m_State == CClient::STATE_AUTHED) { diff --git a/src/engine/shared/econ.h b/src/engine/shared/econ.h index 3ec19e28..daec34c4 100644 --- a/src/engine/shared/econ.h +++ b/src/engine/shared/econ.h @@ -5,6 +5,11 @@ class CEcon { + enum + { + MAX_AUTH_TRIES=3, + }; + class CClient { public: @@ -17,6 +22,7 @@ class CEcon int m_State; int64 m_TimeConnected; + int m_AuthTries; }; CClient m_aClients[NET_MAX_CONSOLE_CLIENTS]; diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 94e2824c..d10c03b6 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -325,7 +325,21 @@ public: class CNetConsole { -private: + 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; @@ -356,6 +370,8 @@ 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(); } }; diff --git a/src/engine/shared/network_console.cpp b/src/engine/shared/network_console.cpp index f77e40f2..13ed3751 100644 --- a/src/engine/shared/network_console.cpp +++ b/src/engine/shared/network_console.cpp @@ -97,9 +97,28 @@ int CNetConsole::Update() NETSOCKET Socket; NETADDR Addr; - while(net_tcp_accept(m_Socket, &Socket, &Addr) > 0) + if(net_tcp_accept(m_Socket, &Socket, &Addr) > 0) { - AcceptClient(Socket, &Addr); + int Index = FindBan(Addr); + if(Index == -1) + AcceptClient(Socket, &Addr); + else + { + 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"); + + net_tcp_send(Socket, aBuf, str_length(aBuf)); + net_tcp_close(Socket); + } } for(int i = 0; i < NET_MAX_CONSOLE_CLIENTS; i++) @@ -110,6 +129,8 @@ int CNetConsole::Update() Drop(i, m_aSlots[i].m_Connection.ErrorString()); } + UpdateBans(); + return 0; } @@ -134,3 +155,65 @@ 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; + } +} -- cgit 1.4.1 From 3209aec45f61a16423c02545b8b4e34eb6324b60 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 13:17:38 +0200 Subject: fixed compiling error on osx --- src/engine/server/server.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 65bb231a..193547cc 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1,6 +1,7 @@ /* (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 -- cgit 1.4.1 From 9cf4facd05a07c457d41624390965c801fe4d325 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 17:07:10 +0200 Subject: fixed a client crash in debug. Closes #806 --- src/engine/client/client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 3d1a5a23..c8bcc83b 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -289,6 +289,7 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotD m_aServerAddressStr[0] = 0; mem_zero(m_aSnapshots, sizeof(m_aSnapshots)); + m_SnapshotStorage.Init(); m_RecivedSnapshots = 0; m_VersionInfo.m_State = CVersionInfo::STATE_INIT; -- cgit 1.4.1 From b25fc26c1cad561bcb4c94a17405058b82dc9e8e Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 18:39:48 +0200 Subject: zero out client memory on startup to prevent more bad surprises --- src/engine/client/client.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index c8bcc83b..bec7d4d6 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1,5 +1,6 @@ /* (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 // qsort #include @@ -2165,7 +2166,12 @@ void CClient::RegisterCommands() m_pConsole->Chain("br_filter_serveraddress", ConchainServerBrowserUpdate, this); } -static CClient *CreateClient() { return new CClient(); } +static CClient *CreateClient() +{ + CClient *pClient = static_cast(mem_alloc(sizeof(CClient), 1)); + mem_zero(pClient, sizeof(CClient)); + return new(pClient) CClient; +} /* Server Time -- cgit 1.4.1 From 50edfd37c0ed57ff793b79d06edd0bde1f6cf1bd Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 31 Jul 2011 23:17:00 +0200 Subject: made 0.6.1 release --- src/game/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/version.h b/src/game/version.h index c7f04b75..76b6d4ab 100644 --- a/src/game/version.h +++ b/src/game/version.h @@ -3,6 +3,6 @@ #ifndef GAME_VERSION_H #define GAME_VERSION_H #include "generated/nethash.cpp" -#define GAME_VERSION "0.6 trunk" +#define GAME_VERSION "0.6.1" #define GAME_NETVERSION "0.6 " GAME_NETVERSION_HASH #endif -- cgit 1.4.1