Conflicts:
	src/engine/shared/config.h
	src/engine/shared/config_variables.h
	src/game/client/gameclient.cpp
	src/game/server/entities/character.cpp
	src/game/server/gamecontext.cpp
	src/game/server/gamecontext.h
This commit is contained in:
GreYFoXGTi 2011-01-24 14:06:55 +02:00
commit f1a8b6b7ad
16 changed files with 1674 additions and 581 deletions

View file

@ -10,6 +10,18 @@
%ds left
== Noch %ds
%i minute left
== Noch %i Minute
%i minutes left
== Noch %i Minuten
%i second left
== Noch %i Sekunde
%i seconds left
== Noch %i Sekunden
%s Right click for context menu.
== %s Rechtsklick für Kontextmenü.
@ -80,7 +92,7 @@ Automatically record demos
== Automatisch Demos aufnehmen
Automatically take game over screenshot
== Automatisch am Ende einer Runde ein Bildschirmfoto erstellen
== Bildschirmfotos autom. nach jeder Runde erstellen
Blue team
== Blaues Team
@ -484,6 +496,9 @@ Mute when not active
Name
== Name
Name plates size
== Größe der Namen
Name:
== Name:
@ -602,7 +617,7 @@ Quads
== Vier.
Quality Textures
== Hochaufgelöste Texturen
== Hochauflösende Texturen
Quick search:
== Schnellsuche:
@ -763,6 +778,9 @@ Skins
Sound
== Ton
Sound error
== Audiofehler
Sound volume
== Lautstärke
@ -811,6 +829,9 @@ Teeworlds %s is out! Download it at www.teeworlds.com!
Texture Compression
== Texturkompression
The audio device couldn't be initialised.
== Das Audiosystem konnte nicht gestartet werden.
The server is running a non-standard tuning on a pure game type.
== Der Server läuft nicht mit Standardeinstellungen.
@ -841,6 +862,9 @@ Type
UI Color
== Menüfarbe
Unable to delete the demo
== Demo konnte nicht gelöscht werden
Up
== Oben
@ -948,30 +972,6 @@ no limit
##### needs translation #####
%i minute left
==
%i minutes left
==
%i second left
==
%i seconds left
==
Name plates size
==
Sound error
==
The audio device couldn't be initialised.
==
Unable to delete the demo
==
##### old translations #####
##### DDRace #####

View file

@ -37,6 +37,9 @@ russian
serbian
== Srpski
spanish
== Español
swedish
== Svenska

File diff suppressed because it is too large Load diff

976
data/languages/spanish.txt Normal file
View file

@ -0,0 +1,976 @@
##### translated strings #####
%d of %d servers, %d players
== %d de %d servidores, %d jugadores
%d%% loaded
== %d%% cargado
%ds left
== faltan %ds
%i minute left
== %i minuto falta
%i minutes left
== %i minutos faltan
%i second left
== %i segundo falta
%i seconds left
== %i segundos faltan
%s Right click for context menu.
== %s click derecho para ver menu.
Abort
== Cancelar
Add
== Agregar
Add Image
== Agregar imagen
Add Quad
== Agregar campo
Add group
== Agregar grupo
Add quads layer
== Agregar campo capa
Add tile layer
== Agregar capa de suelo
Address
== Dirección
Adds a new group
== Agregar nuevo grupo
Adds a new quad
== Agregar nuevo campo
All
== Todos
Alpha
== Alpha
Alpha value of the envelope
== Valor alpha de la envoltura
Always show name plates
== Siempre mostrar apodos
Anim
== Animación
Append
== Anexar
Append map
== Anexar mapa
Are you sure that you want to delete the demo?
== Seguro de eliminar la demo?
Are you sure that you want to quit?
== Seguro que desea salir?
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, entre con su apodo. Es recomendable que verifique su configuración y ajuste las preferencias antes de entrar en un servidor.
Aspect ratio
== Relación de aspecto
Automatically record demos
== Registro automático en demos
Automatically take game over screenshot
== Pantalla game over automáticamente
Blue team
== Equipo azul
Blue team wins!
== Equipo azul gana!
Blue value of the envelope
== Valor azul de la envoltura
Body
== Cuerpo
Border
== Bordes
CCW
== CCW
CW
== CW
Call vote
== Votación
Cancel
== Cancelar
Chat
== Charla
Clear collision
== Limpiar colisión
Clip H
== Clip H
Clip W
== Clip W
Clip X
== Clip X
Clip Y
== Clip Y
Close
== Cerrar
Color
== Color
Color Env
== Color Env
Color TO
== Color TO
Color+
== Color+
Compatible version
== Versión compatible
Connect
== Conectar
Connecting to
== Conectando a
Connection Problems...
== Problemas de Conexión...
Console
== Consola
Constructs collision from this layer
== Construir collisión para esta capa
Controls
== Controles
Creates a new color envelope
== Crear nuevo color de envoltura
Creates a new map
== Crear nuevo mapa
Creates a new pos envelope
== Crear nueva envoltura
Creates a new quad layer
== Crear nueva capa de campo
Creates a new tile layer
== Crear nueva capa de suelo
Current
== Actualmente
Current version: %s
== Versión actual: %s
Custom colors
== Colores personalizados
Decrease
== Reducir
Decrease animation speed
== Reducir velocidad de animación
Delete
== Borrar
Delete demo
== Borrar demo
Delete group
== Borrar grupo
Delete layer
== Borrar capa
Delete this envelope
== Borrar envoltura
Deletes the current quad
== Borrar el campo actual
Deletes the layer
== Borrada la capa
Demos
== Demos
Detail
== Detalles
Disconnect
== Desconectar
Disconnected
== Desconectado
Display Modes
== Modos de exibición
Down
== Abajo
Downloading map
== Bajando mapa
Draw!
== Empate!
Dynamic Camera
== Cámara dinámica
Embed
== Integrar
Embedded
== Embebido
Embeds the image into the map file.
== Integrar la imagen en el mapa
Emoticon
== Emoticon
Enable/disable group for saving
== Activar/Desactivar guardar grupo
Enable/disable layer for saving
== Activar/Desactivar guardar capa
Enter
== Entrar
Envelopes
== Envolturas
Error
== Error
Error loading demo
== Error al cargar demo
Exit
== Salir
Exits from the editor
== Salir del editor
External
== Exterior
FSAA samples
== Muestras FSAA
Favorite
== Favorito
Favorites
== Favoritos
Feet
== Pies
File
== Archivo
File: %s
== Archivo: %s
Filename:
== Archivo:
Filter
== Filtro
Fire
== Disparar
Folder
== Carpeta
Force vote
== Forzar
Fullscreen
== Pantalla Completa
Game
== Juego
Game info
== Info. sobre el juego
Game over
== Fin de Juego
Game type
== Tipo de juego
Game types:
== Tipos de juego:
General
== General
Graphics
== Gráficos
Green value of the envelope
== Valor verde de la envoltura
Grenade
== Granada
Group
== Grupo
HD
== HD
Hammer
== Martillo
Has people playing
== Hay gente jugando
Height
== Alto
High Detail
== Mas detalles (HD)
Hook
== Gancho
Host address
== Dirección de host
Hue
== Matiz
Image
== Imagen
Images
== Imagenes
Increase
== Incrementar
Increase animation speed
== Incrementar velocidad animación
Info
== Info.
Internet
== Internet
Invalid Demo
== Demo invalida
Join blue
== Azul
Join game
== Entrar en juego
Join red
== Rojo
Jump
== Saltar
Kick
== Golpeo
LAN
== LAN
Language
== Lenguaje
Layers
== Capas
Left
== Izquierda
Left mouse button to move. Hold shift to move pivot. Hold ctrl to rotate.
== Izquierdo del ratón para mover. Mantenga mayúsculas para pivotar. Mantenga control para rotar.
Left mouse button to move. Hold shift to move the texture.
== Izquierdo del ratón para mover. Mantenga mayúsculas para mover la textura.
Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point aswell. Right click to delete.
== Izquierdo del ratón para arrastrar. Mantén pulsado Ctrl para ser más precisos. Mantenga mayúsculas para modificar el tiempo también. Derecho del ratón para eliminar.
Lht.
== Luz
Load
== Carga
Load a new image to use in the map
== Carga nueva imagen para usar en el mapa
Load map
== Cargar mapa
Loading
== Cargando
MOTD
== MOTD
Make collision
== Fabricar colisión
Make external
== Fabricar exterior
Map
== Mapa
Max Screenshots
== Max capturas
Max demos
== Max demos
Maximum ping:
== Ping máximo:
Miscellaneous
== Miscelanea
Mouse sens.
== Sens. o ratón
Move left
== Izquierda
Move right
== Derecha
Movement
== Movimiento
Mute when not active
== Silenciar en inactivo
Name
== Nombre
Name plates size
== Tamaño del nombre de placas
Name:
== Nombre:
New
== Nuevo
New folder
== Nueva carpeta
News
== Notícia
Next Envelope
== Nueva encoltura
Next weapon
== Próxima arma
Nickname
== Apodo
No
== No
No password
== Sin contraseña
No servers found
== Ningún servidor encontrado
No servers match your filter criteria
== Ningún servidor corresponde a los critérios de filtro
None
== Ninguno
Normal animation speed
== Velocidad de animación normal
Ok
== Ok
Open
== Abrir
Opens a map and adds everything from that map to the current one
== Abrir mapa y añade todo desde otro mapa al actual
Opens a map for editing
== Abrir mapa para editar
Order
== Pedir
Para X
== Para X
Para Y
== Para Y
Parent Folder
== Carpeta superior
Password
== Contraseña
Password incorrect
== Contraseña incorreta
Ping
== Ping
Pistol
== Pistola
Play
== Asistir
Player
== Jugador
Players
== Jugadores
Please balance teams!
== Por favor, equilibre los equipos!
Pos X
== Pos X
Pos Y
== Pos Y
Pos. Env
== Pos. Env
Pos. TO
== Pos. TO
Pos.+
== Pos.+
Press right mouse button to create a new point
== Pulse el botón derecho del ratón para crear un nuevo punto
Prev. weapon
== Arma anterior
Previous Envelope
== Envoltura anterior
Proof
== Prueba
Quads
== Campos
Quality Textures
== Texturas de calidad
Quick search:
== Pesquisa rápida:
Quit
== Salir
REC
== REC
Reason:
== Razón:
Record demo
== Registro demo
Red team
== Equipo rojo
Red team wins!
== Equipo rojo gana!
Red value of the envelope
== Valor rojo de la envoltura
Refocus
== Reorientar
Refresh
== Actualizar
Refreshing master servers
== Actualizando servidores master
Remote console
== Consola remota
Remove
== Remover
Removes collision from this layer
== Remover colisión para esta capa
Removes the image from the map
== Remover la imagen de este mapa
Removes the image from the map file.
== Remover la imagen para este archivo de mapa.
Replace
== Reemplazar
Replace Image
== Reemplazar Imagen
Replaces the image with a new one
== Reemplazar imagen con una nueva
Reset filter
== Resetar filtro
Reset to defaults
== Resetar por defecto
Resizes the current Quad based on the aspect ratio of the image
== Redimensionar el actual campo según la dimensión de imagen
Rifle
== Laser
Right
== Derecha
Rotation of the brush in degrees. Use left mouse button to drag and change the value. Hold shift to be more precise.
== Rotación del pincel en grados. Utilice el botón izquierdo del ratón para arrastrar y cambiar el valor. Mantenga mayúsculas para ser más precisos.
Rotation of the envelope
== Rotacion de la envoltura
Round
== Ronda
Sample rate
== Frecuencia de muestreo
Sat.
== Sat.
Save
== Guardar
Save As
== Guardar como
Save map
== Guardar mapa
Saves the current map
== Guardar el mapa actual
Saves the current map under a new name
== Guardar el mapa actual en un nuevo juego
Score
== Puntos
Score board
== Tabla de puntos
Score limit
== Puntos máx.
Scoreboard
== Puntuación
Screenshot
== Captura da pantalla
Select group. Right click for properties.
== Seleccionar grupo. Botón derecho para propiedades.
Select image
== Seleccionar imagen
Select layer. Right click for properties.
== Seleccionar capa. Botón derecho para propiedades.
Server details
== Detalles del server
Server info
== Info del server
Server not full
== Servidor incompleto
Settings
== Config.
Shift
== Mayúscula
Shotgun
== Escopeta
Show chat
== Mostrar chat
Show name plates
== Mostrar nicks
Show only supported
== Mostrar solo soportados
Skins
== Skins
Sound
== Sonido
Sound error
== Error de sonido
Sound volume
== Volumem de sonido
Spectate
== Observar
Spectators
== Observadores
Square
== Cuadro
Squares the current quad
== Cuadros del campo actual
Standard gametype
== Tipo de juego normal
Standard map
== Mapa normal
Stop record
== Parar grabación
Sudden Death
== Muerte Súbita
Switch between images and layers managment.
== Cambiar entre las imágenes y la gestión de capas.
Switch curve type
== Interruptor tipo curva
Switch weapon on pickup
== Cambiar de arma
Team
== Equipo
Team chat
== Conv. de equipo
Teeworlds %s is out! Download it at www.teeworlds.com!
== Teeworlds %s ya salió! Descárgalo desde www.teeworlds.com!
Texture Compression
== Compresión de Textura
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.
Tiles
== Suelos
Time limit
== Tiempo máx.
Time limit: %d min
== Tiempo limite: %d min
Toggle group visibility
== Cambiar la visibilidad del grupo
Toggle layer visibility
== Alternar la visibilidad de capa
Toggles the envelope editor.
== Cambia el editor de envoltura.
Try again
== Probar de nuevo
Type
== Tipo
UI Color
== Color de menu
Unable to delete the demo
== No se puede eliminar la demo
Up
== Arriba
Use Clipping
== Usar Tijretazo
Use left mouse button to drag and change the color value. Hold shift to be more precise.
== Utilice el botón izquierdo del ratón para arrastrar y cambiar el valor del color. Mantenga cambio para ser más precisos.
Use left mouse button to drag and change the value. Hold shift to be more precise.
== Utilice el botón izquierdo del ratón para arrastrar y cambiar el valor. Mantenga cambio para ser más precisos.
Use left mouse button to drag and create a brush.
== Utilice el botón izquierdo del ratón para arrastrar y crear un pincel.
Use left mouse button to paint with the brush. Right button clears the brush.
== Utilice el botón izquierdo del ratón para pintar con el pincel. Botón derecho despeja el pincel.
Use sounds
== Usar sonidos
V-Sync
== V-Sync
Version
== Versión
Vote no
== Votar no
Vote yes
== Votar si
Voting
== Votando
Warmup
== Calentamiento
Weapon
== Arma
Welcome to Teeworlds
== Bienvenido a Teeworlds!
Width
== Ancho
X-axis of the envelope
== eje-X de la envoltura
Y-axis of the envelope
== eje-Y de la encoltura
Yes
== Si
You must restart the game for all settings to take effect.
== Debes reiniciar el juego para que los cambios tengan efecto.
Your skin
== Tu skin
ZI
== ZI
ZO
== ZO
[HOME] Restore map focus
== [HOME] Restaurar mapa
[M] Flip brush vertical
== [M] Flip pincel vertical
[N] Flip brush horizontal
== [N] Flip pincel horizontal
[NumPad*] Zoom to normal and remove editor offset
== [NumPad*] Zoom a la normalidad y eliminar editor de desplazamiento
[NumPad+] Zoom in
== [NumPad+] Acercar Zoom
[NumPad-] Zoom out
== [NumPad-] Alejar Zoom
[R] Rotates the brush counter clockwise
== [R] Rotar a la izquierda el pincel
[T] Rotates the brush clockwise
== [T] Rotar a la derecha el pincel
[ctrl+h] Toggle High Detail
== [ctrl+h] Activar detalle alto
[ctrl+m] Toggle animation
== [ctrl+m] Activar animación
[ctrl+p] Toggles proof borders. These borders represent what a player maximum can see.
== [ctrl+p] Alterna bordes de prueba. Estas fronteras representan lo que un jugador puede ver máximo.
no limit
== sin límite
##### needs translation #####
##### old translations #####

View file

@ -22,10 +22,11 @@ enum
CFGFLAG_CLIENT=2,
CFGFLAG_SERVER=4,
CFGFLAG_STORE=8,
CFGFLAG_MASTER=16,
//DDRace
CMDFLAG_CHEAT=16,
CMDFLAG_TIMER=32,
CMDFLAG_HELPERCMD=64
CMDFLAG_CHEAT=32,
CMDFLAG_TIMER=64,
CMDFLAG_HELPERCMD=128
};
#endif

View file

@ -39,7 +39,7 @@ MACRO_CONFIG_INT(BrFilterCompatversion, br_filter_compatversion, 1, 0, 1, CFGFLA
MACRO_CONFIG_INT(BrSort, br_sort, 0, 0, 256, CFGFLAG_SAVE|CFGFLAG_CLIENT, "", -1)
MACRO_CONFIG_INT(BrSortOrder, br_sort_order, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "", -1)
MACRO_CONFIG_INT(BrMaxRequests, br_max_requests, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Number of requests to use when refreshing server browser", -1)
MACRO_CONFIG_INT(BrMaxRequests, br_max_requests, 25, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Number of requests to use when refreshing server browser", -1)
MACRO_CONFIG_INT(SndBufferSize, snd_buffer_size, 512, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound buffer size", -1)
MACRO_CONFIG_INT(SndRate, snd_rate, 48000, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound mixing rate", -1)

View file

@ -4,7 +4,7 @@
void CLineReader::Init(IOHANDLE io)
{
m_BufferMaxSize = 4*1024;
m_BufferMaxSize = sizeof(m_aBuffer);
m_BufferSize = 0;
m_BufferPos = 0;
m_IO = io;
@ -13,6 +13,7 @@ void CLineReader::Init(IOHANDLE io)
char *CLineReader::Get()
{
unsigned LineStart = m_BufferPos;
bool CRLFBreak = false;
while(1)
{
@ -53,10 +54,25 @@ char *CLineReader::Get()
if(m_aBuffer[m_BufferPos] == '\n' || m_aBuffer[m_BufferPos] == '\r')
{
// line found
if(m_aBuffer[m_BufferPos] == '\r' && m_BufferPos+1 < m_BufferSize && m_aBuffer[m_BufferPos+1] == '\n')
if(m_aBuffer[m_BufferPos] == '\r')
{
if(m_BufferPos+1 >= m_BufferSize)
{
// read more to get the connected '\n'
CRLFBreak = true;
++m_BufferPos;
continue;
}
else if(m_aBuffer[m_BufferPos+1] == '\n')
m_aBuffer[m_BufferPos++] = 0;
}
m_aBuffer[m_BufferPos++] = 0;
return &m_aBuffer[LineStart];
}
else if(CRLFBreak)
{
if(m_aBuffer[m_BufferPos] == '\n')
m_aBuffer[m_BufferPos++] = 0;
m_aBuffer[m_BufferPos] = 0;
m_BufferPos++;
return &m_aBuffer[LineStart];
}
else

View file

@ -148,9 +148,9 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
if(ScrollNum > 0)
{
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP))
s_ScrollValue -= 1.0f/ScrollNum;
s_ScrollValue -= 3.0f/ScrollNum;
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
s_ScrollValue += 1.0f/ScrollNum;
s_ScrollValue += 3.0f/ScrollNum;
}
else
ScrollNum = 0;
@ -464,7 +464,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
str_format(aBuf, sizeof(aBuf), "%d", g_Config.m_BrFilterPing);
static float Offset = 0.0f;
DoEditBox(&g_Config.m_BrFilterPing, &EditBox, aBuf, sizeof(aBuf), 12.0f, &Offset);
g_Config.m_BrFilterPing = str_toint(aBuf);
g_Config.m_BrFilterPing = clamp(str_toint(aBuf), 0, 999);
}
View.HSplitBottom(ms_ButtonHeight, &View, &Button);

View file

@ -281,9 +281,9 @@ void CMenus::UiDoListboxStart(void *pId, const CUIRect *pRect, float RowHeight,
if(Num > 0)
{
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP))
gs_ListBoxScrollValue -= 1.0f/Num;
gs_ListBoxScrollValue -= 3.0f/Num;
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
gs_ListBoxScrollValue += 1.0f/Num;
gs_ListBoxScrollValue += 3.0f/Num;
if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f;
if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f;

View file

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

View file

@ -6,7 +6,6 @@
#define CONSOLE_COMMAND(name, params, flags, callback, userdata, help, level)
#endif
CONSOLE_COMMAND("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "Clears the vote list", 4)
CONSOLE_COMMAND("kill_pl", "v", CFGFLAG_SERVER, ConKillPlayer, this, "Kills player v and announces the kill", 2)
CONSOLE_COMMAND("logout", "v", CFGFLAG_SERVER, ConLogOut, this, "Logs player v out from the console", -1)
CONSOLE_COMMAND("helper", "v", CFGFLAG_SERVER, ConSetlvl1, this, "Authenticates player v to the level of 1", 2)

View file

@ -5,20 +5,6 @@
#include <game/server/gamemodes/DDRace.h>
#include <game/version.h>
void CGameContext::ConClearVotes(IConsole::IResult *pResult, void *pUserData, int ClientID)
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->m_pVoteOptionHeap->Reset();
pSelf->m_pVoteOptionFirst = 0;
pSelf->m_pVoteOptionLast = 0;
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "cleared vote options");
CNetMsg_Sv_VoteClearOptions ClearOptionsMsg;
pSelf->Server()->SendPackMsg(&ClearOptionsMsg, MSGFLAG_VITAL, -1);
}
void CGameContext::ConGoLeft(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;

View file

@ -343,7 +343,11 @@ void CCharacter::FireWeapon()
continue;
// set his velocity to fast upward (for now)
GameServer()->CreateHammerHit(m_Pos, Teams()->TeamMask(Team()));
if(length(pTarget->m_Pos-ProjStartPos) > 0.0f)
GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f, Teams()->TeamMask(Team()));
else
GameServer()->CreateHammerHit(ProjStartPos, Teams()->TeamMask(Team()));
vec2 Dir;
if (length(pTarget->m_Pos - m_Pos) > 0.0f)
Dir = normalize(pTarget->m_Pos - m_Pos);

View file

@ -1318,6 +1318,18 @@ void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData, int C
pSelf->Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, -1);
}
void CGameContext::ConClearVotes(IConsole::IResult *pResult, void *pUserData, int ClientID)
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "cleared votes");
CNetMsg_Sv_VoteClearOptions VoteClearOptionsMsg;
pSelf->Server()->SendPackMsg(&VoteClearOptionsMsg, MSGFLAG_VITAL, -1);
pSelf->m_pVoteOptionHeap->Reset();
pSelf->m_pVoteOptionFirst = 0;
pSelf->m_pVoteOptionLast = 0;
}
void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData, int ClientID)
{
CGameContext *pSelf = (CGameContext *)pUserData;
@ -1359,6 +1371,7 @@ void CGameContext::OnConsoleInit()
Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "Sends a server message to all players", 3);
Console()->Register("set_team", "vi", CFGFLAG_SERVER, ConSetTeam, this, "Changes the team of player i1 to team i2", 2);
Console()->Register("addvote", "r", CFGFLAG_SERVER, ConAddVote, this, "Adds a vote entry to the clients", 4);
Console()->Register("clear_votes", "", CFGFLAG_SERVER, ConClearVotes, this, "", 3);
Console()->Register("tune", "si", CFGFLAG_SERVER, ConTuneParam, this, "Modifies tune parameter s to value i", 4);
Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "Resets all tuning", 4);

View file

@ -56,6 +56,7 @@ class CGameContext : public IGameServer
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConAddVote(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConClearVotes(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConVote(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
@ -101,7 +102,6 @@ class CGameContext : public IGameServer
static void ConMove(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConMoveRaw(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConClearVotes(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConInvisMe(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConVisMe(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConInvis(IConsole::IResult *pResult, void *pUserData, int ClientId);
@ -285,4 +285,4 @@ inline int CmaskAll() { return -1; }
inline int CmaskOne(int ClientId) { return 1<<ClientId; }
inline int CmaskAllExceptOne(int ClientId) { return 0x7fffffff^CmaskOne(ClientId); }
inline bool CmaskIsSet(int Mask, int ClientId) { return (Mask&CmaskOne(ClientId)) != 0; }
#endif
#endif

View file

@ -2,6 +2,10 @@
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <base/system.h>
#include <engine/shared/network.h>
#include <engine/shared/config.h>
#include <engine/console.h>
#include <engine/storage.h>
#include <engine/kernel.h>
#include "mastersrv.h"
@ -10,6 +14,7 @@ enum {
MAX_SERVERS_PER_PACKET=128,
MAX_PACKETS=16,
MAX_SERVERS=MAX_SERVERS_PER_PACKET*MAX_PACKETS,
MAX_BANS=128,
EXPIRE_TIME = 90
};
@ -60,11 +65,23 @@ struct CCountPacketData
static CCountPacketData m_CountData;
struct CBanEntry
{
NETADDR m_Address;
int64 m_Expire;
};
static CBanEntry m_aBans[MAX_BANS];
static int m_NumBans = 0;
//static int64 server_expire[MAX_SERVERS];
static CNetClient m_NetChecker; // NAT/FW checker
static CNetClient m_NetOp; // main
IConsole *m_pConsole;
void BuildPackets()
{
CServerEntry *pCurrent = &m_aServers[0];
@ -237,9 +254,61 @@ void PurgeServers()
}
}
int main(int argc, char **argv) // ignore_convention
bool CheckBan(NETADDR Addr)
{
int64 LastBuild = 0;
for(int i = 0; i < m_NumBans; i++)
{
if(net_addr_comp(&m_aBans[i].m_Address, &Addr) == 0)
{
return true;
}
}
Addr.port = 0;
for(int i = 0; i < m_NumBans; i++)
{
if(net_addr_comp(&m_aBans[i].m_Address, &Addr) == 0)
{
return true;
}
}
return false;
}
void ConAddBan(IConsole::IResult *pResult, void *pUser)
{
if(m_NumBans == MAX_BANS)
{
dbg_msg("mastersrv", "error: banlist is full");
return;
}
net_addr_from_str(&m_aBans[m_NumBans].m_Address, pResult->GetString(0));
if(CheckBan(m_aBans[m_NumBans].m_Address))
{
dbg_msg("mastersrv", "duplicate ban: %d.%d.%d.%d:%d",
m_aBans[m_NumBans].m_Address.ip[0], m_aBans[m_NumBans].m_Address.ip[1],
m_aBans[m_NumBans].m_Address.ip[2], m_aBans[m_NumBans].m_Address.ip[3],
m_aBans[m_NumBans].m_Address.port);
return;
}
dbg_msg("mastersrv", "ban added: %d.%d.%d.%d:%d",
m_aBans[m_NumBans].m_Address.ip[0], m_aBans[m_NumBans].m_Address.ip[1],
m_aBans[m_NumBans].m_Address.ip[2], m_aBans[m_NumBans].m_Address.ip[3],
m_aBans[m_NumBans].m_Address.port);
m_NumBans++;
}
void ReloadBans()
{
m_NumBans = 0;
m_pConsole->ExecuteFile("master.cfg");
}
int main(int argc, const char **argv) // ignore_convention
{
int64 LastBuild = 0, LastBanReload = 0;
NETADDR BindAddr;
dbg_logger_stdout();
@ -256,6 +325,18 @@ int main(int argc, char **argv) // ignore_convention
//mem_copy(data.header, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST));
mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT));
IKernel *pKernel = IKernel::Create();
IStorage *pStorage = CreateStorage("Teeworlds", argc, argv);
m_pConsole = CreateConsole(CFGFLAG_MASTER);
m_pConsole->Register("ban", "s", CFGFLAG_MASTER, ConAddBan, 0, "Ban IP from mastersrv");
bool RegisterFail = !pKernel->RegisterInterface(pStorage);
RegisterFail |= !pKernel->RegisterInterface(m_pConsole);
if(RegisterFail)
return -1;
dbg_msg("mastersrv", "started");
@ -268,6 +349,9 @@ int main(int argc, char **argv) // ignore_convention
CNetChunk Packet;
while(m_NetOp.Recv(&Packet))
{
// check if the server is banned
if(CheckBan(Packet.m_Address)) continue;
if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT)+2 &&
mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0)
{
@ -318,6 +402,9 @@ int main(int argc, char **argv) // ignore_convention
// process m_aPackets
while(m_NetChecker.Recv(&Packet))
{
// check if the server is banned
if(CheckBan(Packet.m_Address)) continue;
if(Packet.m_DataSize == sizeof(SERVERBROWSE_FWRESPONSE) &&
mem_comp(Packet.m_pData, SERVERBROWSE_FWRESPONSE, sizeof(SERVERBROWSE_FWRESPONSE)) == 0)
{
@ -338,6 +425,13 @@ int main(int argc, char **argv) // ignore_convention
}
}
if(time_get()-LastBanReload > time_freq()*300)
{
LastBanReload = time_get();
ReloadBans();
}
if(time_get()-LastBuild > time_freq()*5)
{
LastBuild = time_get();