about summary refs log tree commit diff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/client/client.cpp91
-rw-r--r--src/engine/client/graphics.cpp6
-rw-r--r--src/engine/client/graphics.h1
-rw-r--r--src/engine/client/srvbrowse.cpp16
-rw-r--r--src/engine/client/srvbrowse.h1
-rw-r--r--src/engine/console.h9
-rw-r--r--src/engine/server/register.cpp27
-rw-r--r--src/engine/server/register.h3
-rw-r--r--src/engine/server/server.cpp107
-rw-r--r--src/engine/server/server.h4
-rw-r--r--src/engine/shared/config_variables.h1
-rw-r--r--src/engine/shared/console.cpp35
-rw-r--r--src/engine/shared/console.h2
-rw-r--r--src/engine/shared/demorec.cpp45
-rw-r--r--src/engine/shared/demorec.h6
-rw-r--r--src/engine/shared/network.h2
-rw-r--r--src/engine/shared/network_client.cpp2
-rw-r--r--src/engine/shared/network_server.cpp9
18 files changed, 253 insertions, 114 deletions
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp
index ce27e46f..6ddf364f 100644
--- a/src/engine/client/client.cpp
+++ b/src/engine/client/client.cpp
@@ -437,7 +437,11 @@ void CClient::SetState(int s)
 {
 	int Old = m_State;
 	if(g_Config.m_Debug)
-		dbg_msg("client", "state change. last=%d current=%d", m_State, s);
+	{
+		char aBuf[128];
+		str_format(aBuf, sizeof(aBuf), "state change. last=%d current=%d", m_State, s);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf);
+	}
 	m_State = s;
 	if(Old != s)
 		GameClient()->OnStateChange(m_State, Old);
@@ -484,7 +488,8 @@ void CClient::Connect(const char *pAddress)
 
 	str_copy(m_aServerAddressStr, pAddress, sizeof(m_aServerAddressStr));
 
-	dbg_msg("client", "connecting to '%s'", m_aServerAddressStr);
+	str_format(aBuf, sizeof(aBuf), "connecting to '%s'", m_aServerAddressStr);
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
 
 	ServerInfoRequest();
 	str_copy(aBuf, m_aServerAddressStr, sizeof(aBuf));
@@ -502,7 +507,9 @@ void CClient::Connect(const char *pAddress)
 	// TODO: IPv6 support
 	if(net_host_lookup(aBuf, &m_ServerAddress, NETTYPE_IPV4) != 0)
 	{
-		dbg_msg("client", "could not find the address of %s, connecting to localhost", aBuf);
+		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_IPV4);
 	}
 
@@ -520,6 +527,10 @@ void CClient::Connect(const char *pAddress)
 
 void CClient::DisconnectWithReason(const char *pReason)
 {
+	char aBuf[512];
+	str_format(aBuf, sizeof(aBuf), "disconnecting. reason='%s'", pReason?pReason:"unknown");
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
+
 	// stop demo playback and recorder
 	m_DemoPlayer.Stop();
 	m_DemoRecorder.Stop();
@@ -593,9 +604,9 @@ void CClient::SnapInvalidateItem(int SnapId, int Index)
 	if(i)
 	{
 		if((char *)i < (char *)m_aSnapshots[SnapId]->m_pAltSnap || (char *)i > (char *)m_aSnapshots[SnapId]->m_pAltSnap + m_aSnapshots[SnapId]->m_SnapSize)
-			dbg_msg("ASDFASDFASdf", "ASDFASDFASDF");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "snap invalidate problem");
 		if((char *)i >= (char *)m_aSnapshots[SnapId]->m_pSnap && (char *)i < (char *)m_aSnapshots[SnapId]->m_pSnap + m_aSnapshots[SnapId]->m_SnapSize)
-			dbg_msg("ASDFASDFASdf", "ASDFASDFASDF");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "snap invalidate problem");
 		i->m_TypeAndID = -1;
 	}
 }
@@ -764,7 +775,9 @@ const char *CClient::LoadMap(const char *pName, const char *pFilename, unsigned
 	// stop demo recording if we loaded a new map
 	m_DemoRecorder.Stop();
 
-	dbg_msg("client", "loaded map '%s'", pFilename);
+	char aBuf[256];
+	str_format(aBuf, sizeof(aBuf), "loaded map '%s'", pFilename);
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
 	m_RecivedSnapshots = 0;
 
 	str_copy(m_aCurrentMap, pName, sizeof(m_aCurrentMap));
@@ -779,7 +792,8 @@ const char *CClient::LoadMapSearch(const char *pMapName, int WantedCrc)
 {
 	const char *pError = 0;
 	char aBuf[512];
-	dbg_msg("client", "loading map, map=%s wanted crc=%08x", pMapName, WantedCrc);
+	str_format(aBuf, sizeof(aBuf), "loading map, map=%s wanted crc=%08x", pMapName, WantedCrc);
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
 	SetState(IClient::STATE_LOADING);
 
 	// try the normal maps folder
@@ -816,9 +830,11 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 			unsigned char *pVersionData = (unsigned char*)pPacket->m_pData + sizeof(VERSIONSRV_VERSION);
 			int VersionMatch = !mem_comp(pVersionData, VERSION_DATA, sizeof(VERSION_DATA));
 
-			dbg_msg("client/version", "version does %s (%d.%d.%d)",
+			char aBuf[256];
+			str_format(aBuf, sizeof(aBuf), "version does %s (%d.%d.%d)",
 				VersionMatch ? "match" : "NOT match",
 				pVersionData[1], pVersionData[2], pVersionData[3]);
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/version", aBuf);
 
 			// assume version is out of date when version-data doesn't match
 			if (!VersionMatch)
@@ -954,7 +970,7 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 
 					if(!pError)
 					{
-						dbg_msg("client/network", "loading done");
+						m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
 						SendReady();
 						GameClient()->OnConnected();
 					}
@@ -962,7 +978,9 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 					{
 						str_format(m_aMapdownloadFilename, sizeof(m_aMapdownloadFilename), "downloadedmaps/%s_%08x.map", pMap, MapCrc);
 
-						dbg_msg("client/network", "starting to download map to '%s'", m_aMapdownloadFilename);
+						char aBuf[256];
+						str_format(aBuf, sizeof(aBuf), "starting to download map to '%s'", m_aMapdownloadFilename);
+						m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", aBuf);
 
 						m_MapdownloadChunk = 0;
 						str_copy(m_aMapdownloadName, pMap, sizeof(m_aMapdownloadName));
@@ -976,7 +994,10 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 						SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH);
 
 						if(g_Config.m_Debug)
-							dbg_msg("client/network", "requested chunk %d", m_MapdownloadChunk);
+						{
+							str_format(aBuf, sizeof(aBuf), "requested chunk %d", m_MapdownloadChunk);
+							m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client/network", aBuf);
+						}
 					}
 				}
 			}
@@ -999,7 +1020,7 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 				if(Last)
 				{
 					const char *pError;
-					dbg_msg("client/network", "download complete, loading map");
+					m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "download complete, loading map");
 
 					io_close(m_MapdownloadFile);
 					m_MapdownloadFile = 0;
@@ -1010,7 +1031,7 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 					pError = LoadMap(m_aMapdownloadName, m_aMapdownloadFilename, m_MapdownloadCrc);
 					if(!pError)
 					{
-						dbg_msg("client/network", "loading done");
+						m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
 						SendReady();
 						GameClient()->OnConnected();
 					}
@@ -1027,7 +1048,11 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 					SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH);
 
 					if(g_Config.m_Debug)
-						dbg_msg("client/network", "requested chunk %d", m_MapdownloadChunk);
+					{
+						char aBuf[256];
+						str_format(aBuf, sizeof(aBuf), "requested chunk %d", m_MapdownloadChunk);
+						m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client/network", aBuf);
+					}
 				}
 			}
 			else if(Msg == NETMSG_PING)
@@ -1048,7 +1073,11 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 					GameClient()->OnRconLine(pLine);
 			}
 			else if(Msg == NETMSG_PING_REPLY)
-				dbg_msg("client/network", "latency %.2f", (time_get() - m_PingStartTime)*1000 / (float)time_freq());
+			{
+				char aBuf[256];
+				str_format(aBuf, sizeof(aBuf), "latency %.2f", (time_get() - m_PingStartTime)*1000 / (float)time_freq());
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client/network", aBuf);
+			}
 			else if(Msg == NETMSG_INPUTTIMING)
 			{
 				int InputPredTick = Unpacker.GetInt();
@@ -1143,7 +1172,11 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 								// couldn't find the delta snapshots that the server used
 								// to compress this snapshot. force the server to resync
 								if(g_Config.m_Debug)
-									dbg_msg("client", "error, couldn't find the delta snapshot");
+								{
+									char aBuf[256];
+									str_format(aBuf, sizeof(aBuf), "error, couldn't find the delta snapshot");
+									m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf);
+								}
 
 								// ack snapshot
 								// TODO: combine this with the input message
@@ -1172,7 +1205,7 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 						SnapSize = m_SnapshotDelta.UnpackDelta(pDeltaShot, pTmpBuffer3, pDeltaData, DeltaSize);
 						if(SnapSize < 0)
 						{
-							dbg_msg("client", "delta unpack failed!");
+							m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "delta unpack failed!");
 							return;
 						}
 
@@ -1180,8 +1213,10 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
 						{
 							if(g_Config.m_Debug)
 							{
-								dbg_msg("client", "snapshot crc error #%d - tick=%d wantedcrc=%d gotcrc=%d compressed_size=%d delta_tick=%d",
+								char aBuf[256];
+								str_format(aBuf, sizeof(aBuf), "snapshot crc error #%d - tick=%d wantedcrc=%d gotcrc=%d compressed_size=%d delta_tick=%d",
 									m_SnapCrcErrors, GameTick, Crc, pTmpBuffer3->Crc(), CompleteSize, DeltaTick);
+								m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf);
 							}
 
 							m_SnapCrcErrors++;
@@ -1273,14 +1308,16 @@ void CClient::PumpNetwork()
 		{
 			SetState(IClient::STATE_OFFLINE);
 			Disconnect();
-			dbg_msg("client", "offline error='%s'", m_NetClient.ErrorString());
+			char aBuf[256];
+			str_format(aBuf, sizeof(aBuf), "offline error='%s'", m_NetClient.ErrorString());
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
 		}
 
 		//
 		if(State() == IClient::STATE_CONNECTING && m_NetClient.State() == NETSTATE_ONLINE)
 		{
 			// we switched to online
-			dbg_msg("client", "connected, sending info");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", "connected, sending info");
 			SetState(IClient::STATE_LOADING);
 			SendInfo();
 		}
@@ -1434,7 +1471,7 @@ void CClient::Update()
 
 			if(NewPredTick < m_aSnapshots[SNAP_PREV]->m_Tick-SERVER_TICK_SPEED || NewPredTick > m_aSnapshots[SNAP_PREV]->m_Tick+SERVER_TICK_SPEED)
 			{
-				dbg_msg("client", "prediction time reset!");
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", "prediction time reset!");
 				m_PredictedTime.Init(m_aSnapshots[SNAP_CURRENT]->m_Tick*time_freq()/50);
 			}
 
@@ -1477,7 +1514,7 @@ void CClient::Update()
 		{
 			if(Now > ActionTaken+time_freq()*2)
 			{
-				dbg_msg("stress", "reconnecting!");
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "stress", "reconnecting!");
 				Connect(g_Config.m_DbgStressServer);
 				ActionTaken = Now;
 			}
@@ -1590,7 +1627,9 @@ void CClient::Run()
 		return;
 
 	GameClient()->OnInit();
-	dbg_msg("client", "version %s", GameClient()->NetVersion());
+	char aBuf[256];
+	str_format(aBuf, sizeof(aBuf), "version %s", GameClient()->NetVersion());
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
 
 	// open socket
 	{
@@ -1836,7 +1875,7 @@ const char *CClient::DemoPlayer_Play(const char *pFilename)
 	// try to start playback
 	m_DemoPlayer.SetListner(this);
 
-	if(m_DemoPlayer.Load(Storage(), pFilename))
+	if(m_DemoPlayer.Load(Storage(), m_pConsole, pFilename))
 		return "error loading demo";
 
 	// load map
@@ -1887,12 +1926,12 @@ void CClient::Con_Play(IConsole::IResult *pResult, void *pUserData)
 void CClient::DemoRecorder_Start(const char *pFilename)
 {
 	if(State() != IClient::STATE_ONLINE)
-		dbg_msg("demorec/record", "client is not online");
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demorec/record", "client is not online");
 	else
 	{
 		char aFilename[512];
 		str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pFilename);
-		m_DemoRecorder.Start(Storage(), aFilename, GameClient()->NetVersion(), m_aCurrentMap, m_CurrentMapCrc, "client");
+		m_DemoRecorder.Start(Storage(), m_pConsole, aFilename, GameClient()->NetVersion(), m_aCurrentMap, m_CurrentMapCrc, "client");
 	}
 }
 
diff --git a/src/engine/client/graphics.cpp b/src/engine/client/graphics.cpp
index 09ee4784..1e9a79cf 100644
--- a/src/engine/client/graphics.cpp
+++ b/src/engine/client/graphics.cpp
@@ -25,6 +25,7 @@
 #include <engine/graphics.h>
 #include <engine/storage.h>
 #include <engine/keys.h>
+#include <engine/console.h>
 
 #include <math.h>
 #include <time.h>
@@ -446,7 +447,9 @@ void CGraphics_OpenGL::ScreenshotDirect(const char *pFilename)
 			io_close(File);
 	
 		// save png
-		dbg_msg("client", "saved screenshot to '%s'", aWholePath);
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
 		png_open_file_write(&Png, aWholePath); // ignore_convention
 		png_set_data(&Png, w, h, 8, PNG_TRUECOLOR, (unsigned char *)pPixelData); // ignore_convention
 		png_close_file(&Png); // ignore_convention
@@ -663,6 +666,7 @@ void CGraphics_OpenGL::QuadsText(float x, float y, float Size, float r, float g,
 bool CGraphics_OpenGL::Init()
 {
 	m_pStorage = Kernel()->RequestInterface<IStorage>();
+	m_pConsole = Kernel()->RequestInterface<IConsole>();
 	
 	// Set all z to -5.0f
 	for(int i = 0; i < MAX_VERTICES; i++)
diff --git a/src/engine/client/graphics.h b/src/engine/client/graphics.h
index cb8681f3..fa360a22 100644
--- a/src/engine/client/graphics.h
+++ b/src/engine/client/graphics.h
@@ -5,6 +5,7 @@ class CGraphics_OpenGL : public IEngineGraphics
 {
 protected:
 	class IStorage *m_pStorage;
+	class IConsole *m_pConsole;
 	
 	//
 	typedef struct { float x, y, z; } CPoint;
diff --git a/src/engine/client/srvbrowse.cpp b/src/engine/client/srvbrowse.cpp
index d0c8393d..aed0d514 100644
--- a/src/engine/client/srvbrowse.cpp
+++ b/src/engine/client/srvbrowse.cpp
@@ -9,6 +9,7 @@
 #include <engine/shared/engine.h>
 
 #include <engine/masterserver.h>
+#include <engine/console.h>
 #include <engine/config.h>
 
 #include <mastersrv/mastersrv.h>
@@ -62,6 +63,7 @@ void CServerBrowser::SetBaseInfo(class CNetClient *pClient, const char *pNetVers
 	m_pNetClient = pClient;
 	str_copy(m_aNetVersion, pNetVersion, sizeof(m_aNetVersion));
 	m_pMasterServer = Kernel()->RequestInterface<IMasterServer>();
+	m_pConsole = Kernel()->RequestInterface<IConsole>();
 	IConfig *pConfig = Kernel()->RequestInterface<IConfig>();
 	if(pConfig)
 		pConfig->RegisterCallback(ConfigSaveCallback, this);
@@ -514,7 +516,7 @@ void CServerBrowser::Refresh(int Type)
 		}
 
 		if(g_Config.m_Debug)
-			dbg_msg("client", "broadcasting for servers");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "broadcasting for servers");
 	}
 	else if(Type == IServerBrowser::TYPE_INTERNET)
 		m_NeedRefresh = 1;
@@ -532,9 +534,11 @@ void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) cons
 
 	if(g_Config.m_Debug)
 	{
-		dbg_msg("client", "requesting server info from %d.%d.%d.%d:%d",
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf),"requesting server info from %d.%d.%d.%d:%d",
 			Addr.ip[0], Addr.ip[1], Addr.ip[2],
 			Addr.ip[3], Addr.port);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf);
 	}
 
 	/*mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
@@ -595,7 +599,7 @@ void CServerBrowser::Update()
 		}
 
 		if(g_Config.m_Debug)
-			dbg_msg("client", "requesting server list");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "requesting server list");
 	}
 
 	// do timeouts
@@ -676,7 +680,11 @@ void CServerBrowser::AddFavorite(const NETADDR &Addr)
 		pEntry->m_Info.m_Favorite = 1;
 
     if(g_Config.m_Debug)
-        dbg_msg("", "added fav, %d.%d.%d.%d:%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], Addr.port);
+	{
+		char aBuf[256];
+        str_format(aBuf, sizeof(aBuf), "added fav, %d.%d.%d.%d:%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], Addr.port);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf);
+	}
 }
 
 void CServerBrowser::RemoveFavorite(const NETADDR &Addr)
diff --git a/src/engine/client/srvbrowse.h b/src/engine/client/srvbrowse.h
index 1c255792..ecaed7ef 100644
--- a/src/engine/client/srvbrowse.h
+++ b/src/engine/client/srvbrowse.h
@@ -50,6 +50,7 @@ public:
 private:
 	CNetClient *m_pNetClient;
 	IMasterServer *m_pMasterServer;
+	class IConsole *m_pConsole;
 	char m_aNetVersion[128];
 
 	CHeap m_ServerlistHeap;
diff --git a/src/engine/console.h b/src/engine/console.h
index 05034734..80a995c3 100644
--- a/src/engine/console.h
+++ b/src/engine/console.h
@@ -8,6 +8,13 @@ class IConsole : public IInterface
 	MACRO_INTERFACE("console", 0)
 public:
 
+	enum
+	{
+		OUTPUT_LEVEL_STANDARD=0,
+		OUTPUT_LEVEL_ADDINFO,
+		OUTPUT_LEVEL_DEBUG
+	};
+
 	// TODO: rework this interface to reduce the amount of virtual calls
 	class IResult
 	{
@@ -51,7 +58,7 @@ public:
 	virtual void ExecuteFile(const char *pFilename) = 0;
 	
 	virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData) = 0;
-	virtual void Print(const char *pStr) = 0;
+	virtual void Print(int Level, const char *pFrom, const char *pStr) = 0;
 };
 
 extern IConsole *CreateConsole(int FlagMask);
diff --git a/src/engine/server/register.cpp b/src/engine/server/register.cpp
index e9616ca1..925fef30 100644
--- a/src/engine/server/register.cpp
+++ b/src/engine/server/register.cpp
@@ -2,6 +2,7 @@
 #include <engine/shared/network.h>
 #include <engine/shared/config.h>
 #include <engine/shared/engine.h>
+#include <engine/console.h>
 #include <engine/masterserver.h>
 
 #include <mastersrv/mastersrv.h>
@@ -12,6 +13,7 @@ CRegister::CRegister()
 {
 	m_pNetServer = 0;
 	m_pMasterServer = 0;
+	m_pConsole = 0;
 
 	m_RegisterState = REGISTERSTATE_START;
 	m_RegisterStateStart = 0;
@@ -87,10 +89,11 @@ void CRegister::RegisterGotCount(CNetChunk *pChunk)
 	}
 }
 
-void CRegister::Init(CNetServer *pNetServer, IEngineMasterServer *pMasterServer)
+void CRegister::Init(CNetServer *pNetServer, IEngineMasterServer *pMasterServer, IConsole *pConsole)
 {
 	m_pNetServer = pNetServer;
 	m_pMasterServer = pMasterServer;
+	m_pConsole = pConsole;
 }
 
 void CRegister::RegisterUpdate()
@@ -109,7 +112,7 @@ void CRegister::RegisterUpdate()
 		m_RegisterFirst = 1;
 		RegisterNewState(REGISTERSTATE_UPDATE_ADDRS);
 		m_pMasterServer->RefreshAddresses();
-		dbg_msg("register", "refreshing ip addresses");
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "refreshing ip addresses");
 	}
 	else if(m_RegisterState == REGISTERSTATE_UPDATE_ADDRS)
 	{
@@ -134,7 +137,7 @@ void CRegister::RegisterUpdate()
 				}
 			}
 			
-			dbg_msg("register", "fetching server counts");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "fetching server counts");
 			RegisterNewState(REGISTERSTATE_QUERY_COUNT);
 		}
 	}
@@ -176,12 +179,14 @@ void CRegister::RegisterUpdate()
 			m_RegisterRegisteredServer = Best;
 			if(m_RegisterRegisteredServer == -1)
 			{
-				dbg_msg("register", "WARNING: No master servers. Retrying in 60 seconds");
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "WARNING: No master servers. Retrying in 60 seconds");
 				RegisterNewState(REGISTERSTATE_ERROR);
 			}
 			else
 			{			
-				dbg_msg("register", "choosen '%s' as master, sending heartbeats", m_pMasterServer->GetName(m_RegisterRegisteredServer));
+				char aBuf[256];
+				str_format(aBuf, sizeof(aBuf), "choosen '%s' as master, sending heartbeats", m_pMasterServer->GetName(m_RegisterRegisteredServer));
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", aBuf);
 				m_aMasterserverInfo[m_RegisterRegisteredServer].m_LastSend = 0;
 				RegisterNewState(REGISTERSTATE_HEARTBEAT);
 			}
@@ -198,14 +203,14 @@ void CRegister::RegisterUpdate()
 		
 		if(Now > m_RegisterStateStart+Freq*60)
 		{
-			dbg_msg("register", "WARNING: Master server is not responding, switching master");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "WARNING: Master server is not responding, switching master");
 			RegisterNewState(REGISTERSTATE_START);
 		}
 	}
 	else if(m_RegisterState == REGISTERSTATE_REGISTERED)
 	{
 		if(m_RegisterFirst)
-			dbg_msg("register", "server registered");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "server registered");
 			
 		m_RegisterFirst = 0;
 		
@@ -258,15 +263,17 @@ int CRegister::RegisterProcessPacket(CNetChunk *pPacket)
 		mem_comp(pPacket->m_pData, SERVERBROWSE_FWOK, sizeof(SERVERBROWSE_FWOK)) == 0)
 	{
 		if(m_RegisterFirst)
-			dbg_msg("register", "no firewall/nat problems detected");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "no firewall/nat problems detected");
 		RegisterNewState(REGISTERSTATE_REGISTERED);
 		return 1;
 	}
 	else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_FWERROR) &&
 		mem_comp(pPacket->m_pData, SERVERBROWSE_FWERROR, sizeof(SERVERBROWSE_FWERROR)) == 0)
 	{
-		dbg_msg("register", "ERROR: the master server reports that clients can not connect to this server.");
-		dbg_msg("register", "ERROR: configure your firewall/nat to let through udp on port %d.", g_Config.m_SvPort);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "ERROR: the master server reports that clients can not connect to this server.");
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "ERROR: configure your firewall/nat to let through udp on port %d.", g_Config.m_SvPort);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", aBuf);
 		RegisterNewState(REGISTERSTATE_ERROR);
 		return 1;
 	}
diff --git a/src/engine/server/register.h b/src/engine/server/register.h
index ea1d9dcc..bc98b7d9 100644
--- a/src/engine/server/register.h
+++ b/src/engine/server/register.h
@@ -23,6 +23,7 @@ class CRegister
 
 	class CNetServer *m_pNetServer;
 	class IEngineMasterServer *m_pMasterServer;
+	class IConsole *m_pConsole;
 
 	int m_RegisterState;
 	int64 m_RegisterStateStart;
@@ -40,7 +41,7 @@ class CRegister
 
 public:
 	CRegister();
-	void Init(class CNetServer *pNetServer, class IEngineMasterServer *pMasterServer);
+	void Init(class CNetServer *pNetServer, class IEngineMasterServer *pMasterServer, class IConsole *pConsole);
 	void RegisterUpdate();
 	int RegisterProcessPacket(class CNetChunk *pPacket);
 };
diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp
index 9c2af790..710b54e1 100644
--- a/src/engine/server/server.cpp
+++ b/src/engine/server/server.cpp
@@ -192,7 +192,9 @@ int CServer::TrySetClientName(int ClientID, const char *pName)
 	// trim the name
 	str_copy(aTrimmedName, StrLtrim(pName), sizeof(aTrimmedName));
 	StrRtrim(aTrimmedName);
-	dbg_msg("", "'%s' -> '%s'", pName, aTrimmedName);
+	char aBuf[256];
+	str_format(aBuf, sizeof(aBuf), "'%s' -> '%s'", pName, aTrimmedName);
+	Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
 	pName = aTrimmedName;
 	
 	
@@ -535,10 +537,19 @@ int CServer::NewClientCallback(int ClientId, void *pUser)
 	return 0;
 }
 
-int CServer::DelClientCallback(int ClientId, void *pUser)
+int CServer::DelClientCallback(int ClientId, const char *pReason, void *pUser)
 {
 	CServer *pThis = (CServer *)pUser;
 	
+	NETADDR Addr = pThis->m_NetServer.ClientAddr(ClientId);
+	char aBuf[256];
+	str_format(aBuf, sizeof(aBuf), "client dropped. cid=%d ip=%d.%d.%d.%d reason=\"%s\"",
+		ClientId,
+		Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3],
+		pReason
+	);
+	pThis->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
+
 	// notify the mod about the drop
 	if(pThis->m_aClients[ClientId].m_State >= CClient::STATE_READY)
 		pThis->GameServer()->OnClientDrop(ClientId);
@@ -670,7 +681,11 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
 				SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientId, true);
 				
 				if(g_Config.m_Debug)
-					dbg_msg("server", "sending chunk %d with size %d", Chunk, ChunkSize);
+				{
+					char aBuf[256];
+					str_format(aBuf, sizeof(aBuf), "sending chunk %d with size %d", Chunk, ChunkSize);
+					Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
+				}
 			}
 			else if(Msg == NETMSG_READY)
 			{
@@ -678,8 +693,10 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
 				{
 					Addr = m_NetServer.ClientAddr(ClientId);
 					
-					dbg_msg("server", "player is ready. ClientId=%x ip=%d.%d.%d.%d",
+					char aBuf[256];
+					str_format(aBuf, sizeof(aBuf), "player is ready. ClientId=%x ip=%d.%d.%d.%d",
 						ClientId, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
+					Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
 					m_aClients[ClientId].m_State = CClient::STATE_READY;
 					GameServer()->OnClientConnected(ClientId);
 				}
@@ -690,8 +707,10 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
 				{
 					Addr = m_NetServer.ClientAddr(ClientId);
 					
-					dbg_msg("server", "player has entered the game. ClientId=%x ip=%d.%d.%d.%d",
+					char aBuf[256];
+					str_format(aBuf, sizeof(aBuf), "player has entered the game. ClientId=%x ip=%d.%d.%d.%d",
 						ClientId, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
+					Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
 					m_aClients[ClientId].m_State = CClient::STATE_INGAME;
 					GameServer()->OnClientEnter(ClientId);
 				}
@@ -754,7 +773,9 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
 				
 				if(Unpacker.Error() == 0 && m_aClients[ClientId].m_Authed)
 				{
-					dbg_msg("server", "ClientId=%d rcon='%s'", ClientId, pCmd);
+					char aBuf[256];
+					str_format(aBuf, sizeof(aBuf), "ClientId=%d rcon='%s'", ClientId, pCmd);
+					Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
 					Console()->ExecuteLine(pCmd);
 				}
 			}
@@ -778,7 +799,9 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
 						
 						m_aClients[ClientId].m_Authed = 1;
 						SendRconLine(ClientId, "Authentication successful. Remote console access granted.");
-						dbg_msg("server", "ClientId=%d authed", ClientId);
+						char aBuf[256];
+						str_format(aBuf, sizeof(aBuf), "ClientId=%d authed", ClientId);
+						Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
 					}
 					else
 					{
@@ -804,8 +827,10 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
 					aBuf[b*3+3] = 0;
 				}
 
-				dbg_msg("server", "strange message ClientId=%d msg=%d data_size=%d", ClientId, Msg, pPacket->m_DataSize);
-				dbg_msg("server", "%s", aBuf);
+				char aBufMsg[256];
+				str_format(aBufMsg, sizeof(aBufMsg), "strange message ClientId=%d msg=%d data_size=%d", ClientId, Msg, pPacket->m_DataSize);
+				Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBufMsg);
+				Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
 				
 			}
 		}
@@ -963,7 +988,9 @@ int CServer::LoadMap(const char *pMapName)
 	
 	// get the crc of the map
 	m_CurrentMapCrc = m_pMap->Crc();
-	dbg_msg("server", "%s crc is %08x", aBuf, m_CurrentMapCrc);
+	char aBufMsg[256];
+	str_format(aBufMsg, sizeof(aBufMsg), "%s crc is %08x", aBuf, m_CurrentMapCrc);
+	Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBufMsg);
 		
 	str_copy(m_aCurrentMap, pMapName, sizeof(m_aCurrentMap));
 	//map_set(df);
@@ -986,9 +1013,9 @@ void CServer::InitEngine(const char *pAppname)
 	m_Engine.Init(pAppname);
 }
 
-void CServer::InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer)
+void CServer::InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer, IConsole *pConsole)
 {
-	m_Register.Init(pNetServer, pMasterServer);
+	m_Register.Init(pNetServer, pMasterServer, pConsole);
 }
 
 int CServer::Run()
@@ -1033,10 +1060,13 @@ int CServer::Run()
 
 	m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this);
 	
-	dbg_msg("server", "server name is '%s'", g_Config.m_SvName);
+	char aBuf[256];
+	str_format(aBuf, sizeof(aBuf), "server name is '%s'", g_Config.m_SvName);
+	Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
 	
 	GameServer()->OnInit();
-	dbg_msg("server", "version %s", GameServer()->NetVersion());
+	str_format(aBuf, sizeof(aBuf), "version %s", GameServer()->NetVersion());
+	Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
 
 	// process pending commands
 	m_pConsole->StoreCommands(false);
@@ -1050,7 +1080,10 @@ int CServer::Run()
 		m_GameStartTime = time_get();
 	
 		if(g_Config.m_Debug)
-			dbg_msg("server", "baseline memory usage %dk", mem_stats()->allocated/1024);
+		{
+			str_format(aBuf, sizeof(aBuf), "baseline memory usage %dk", mem_stats()->allocated/1024);
+			Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
+		}
 
 		while(m_RunServer)
 		{
@@ -1086,7 +1119,8 @@ int CServer::Run()
 				}
 				else
 				{
-					dbg_msg("server", "failed to load map. mapname='%s'", g_Config.m_SvMap);
+					str_format(aBuf, sizeof(aBuf), "failed to load map. mapname='%s'", g_Config.m_SvMap);
+					Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
 					str_copy(g_Config.m_SvMap, m_aCurrentMap, sizeof(g_Config.m_SvMap));
 				}
 			}
@@ -1194,7 +1228,7 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser)
 
 		if(ClientId < 0 || ClientId >= MAX_CLIENTS || ((CServer *)pUser)->m_aClients[ClientId].m_State == CClient::STATE_EMPTY)
 		{
-			dbg_msg("server", "invalid client id");
+			((CServer *)pUser)->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid client id");
 			return;
 		}
 
@@ -1205,10 +1239,12 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser)
 	Addr.port = 0;
 	net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
 	
+	char aBuf[256];
 	if(Minutes)
-		dbg_msg("server", "banned %s for %d minutes", aAddrStr, Minutes);
+		str_format(aBuf, sizeof(aBuf), "banned %s for %d minutes", aAddrStr, Minutes);
 	else
-		dbg_msg("server", "banned %s for life", aAddrStr);
+		str_format(aBuf, sizeof(aBuf), "banned %s for life", aAddrStr);
+	((CServer *)pUser)->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
 }
 
 void CServer::ConUnban(IConsole::IResult *pResult, void *pUser)
@@ -1217,19 +1253,27 @@ void CServer::ConUnban(IConsole::IResult *pResult, void *pUser)
 	CServer *pServer = (CServer *)pUser;
 	const char *pStr = pResult->GetString(0);
 	
-	if(net_addr_from_str(&Addr, pStr) == 0)
-		pServer->BanRemove(Addr);
+	if(net_addr_from_str(&Addr, pStr) == 0 && !pServer->BanRemove(Addr))
+	{
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "unbanned %d.%d.%d.%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
+		pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
+	}
 	else if(StrAllnum(pStr))
 	{
 		int BanIndex = str_toint(pStr);
 		CNetServer::CBanInfo Info;
 		if(BanIndex < 0 || !pServer->m_NetServer.BanGet(BanIndex, &Info))
-			dbg_msg("server", "invalid ban index");
-		else
-			pServer->BanRemove(Info.m_Addr);
+			pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid ban index");
+		else if(!pServer->BanRemove(Info.m_Addr))
+		{
+			char aBuf[256];
+			str_format(aBuf, sizeof(aBuf), "unbanned %d.%d.%d.%d", Info.m_Addr.ip[0], Info.m_Addr.ip[1], Info.m_Addr.ip[2], Info.m_Addr.ip[3]);
+			pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
+		}
 	}
 	else
-		dbg_msg("server", "invalid network address");
+		pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "invalid network address");
 }
 
 void CServer::ConBans(IConsole::IResult *pResult, void *pUser)
@@ -1254,12 +1298,10 @@ void CServer::ConBans(IConsole::IResult *pResult, void *pUser)
 			unsigned t = Info.m_Expires - Now;
 			str_format(aBuf, sizeof(aBuf), "#%d %d.%d.%d.%d for %d minutes and %d seconds", i, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], t/60, t%60);
 		}
-		pServer->Console()->Print(aBuf);
-		dbg_msg("server", "%s", aBuf);
+		pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
 	}
 	str_format(aBuf, sizeof(aBuf), "%d ban(s)", Num);
-	pServer->Console()->Print(aBuf);
-	dbg_msg("server", "%s", aBuf);
+	pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
 }
 
 void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
@@ -1281,8 +1323,7 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
 			else
 				str_format(aBuf, sizeof(aBuf), "id=%d addr=%d.%d.%d.%d:%d connecting",
 					i, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], Addr.port);
-			pServer->Console()->Print(aBuf);
-			dbg_msg("server", "%s", aBuf);
+			pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
 		}
 	}
 }
@@ -1296,7 +1337,7 @@ void CServer::ConRecord(IConsole::IResult *pResult, void *pUser)
 {
 	char aFilename[512];
 	str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pResult->GetString(0));
-	((CServer *)pUser)->m_DemoRecorder.Start(((CServer *)pUser)->Storage(), aFilename, ((CServer *)pUser)->GameServer()->NetVersion(), ((CServer *)pUser)->m_aCurrentMap, ((CServer *)pUser)->m_CurrentMapCrc, "server");
+	((CServer *)pUser)->m_DemoRecorder.Start(((CServer *)pUser)->Storage(), ((CServer *)pUser)->Console(), aFilename, ((CServer *)pUser)->GameServer()->NetVersion(), ((CServer *)pUser)->m_aCurrentMap, ((CServer *)pUser)->m_CurrentMapCrc, "server");
 }
 
 void CServer::ConStopRecord(IConsole::IResult *pResult, void *pUser)
@@ -1399,7 +1440,7 @@ int main(int argc, const char **argv) // ignore_convention
 	IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); // ignore_convention
 	IConfig *pConfig = CreateConfig();
 	
-	pServer->InitRegister(&pServer->m_NetServer, pEngineMasterServer);
+	pServer->InitRegister(&pServer->m_NetServer, pEngineMasterServer, pConsole);
 
 	{
 		bool RegisterFail = false;
diff --git a/src/engine/server/server.h b/src/engine/server/server.h
index 70c8899c..756c1054 100644
--- a/src/engine/server/server.h
+++ b/src/engine/server/server.h
@@ -152,7 +152,7 @@ public:
 	void DoSnapshot();
 
 	static int NewClientCallback(int ClientId, void *pUser);
-	static int DelClientCallback(int ClientId, void *pUser);
+	static int DelClientCallback(int ClientId, const char *pReason, void *pUser);
 
 	void SendMap(int ClientId);
 	void SendRconLine(int ClientId, const char *pLine);
@@ -172,7 +172,7 @@ public:
 	int LoadMap(const char *pMapName);
 
 	void InitEngine(const char *pAppname);
-	void InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer);
+	void InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer, IConsole *pConsole);
 	int Run();
 
 	static void ConKick(IConsole::IResult *pResult, void *pUser);
diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h
index 9fb67e80..03d8f907 100644
--- a/src/engine/shared/config_variables.h
+++ b/src/engine/shared/config_variables.h
@@ -10,6 +10,7 @@ MACRO_CONFIG_STR(PlayerName, player_name, 24, "nameless tee", CFGFLAG_SAVE|CFGFL
 MACRO_CONFIG_STR(ClanName, clan_name, 32, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "(not used)")
 MACRO_CONFIG_STR(Password, password, 32, "", CFGFLAG_CLIENT|CFGFLAG_SERVER, "Password to the server")
 MACRO_CONFIG_STR(Logfile, logfile, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT|CFGFLAG_SERVER, "Filename to log all output to")
+MACRO_CONFIG_INT(ConsoleOutputLevel, console_output_level, 0, 0, 2, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Adjusts the amount of information in the console")
 
 MACRO_CONFIG_INT(ClCpuThrottle, cl_cpu_throttle, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
 MACRO_CONFIG_INT(ClEditor, cl_editor, 0, 0, 1, CFGFLAG_CLIENT, "")
diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp
index 367e7e87..dc2e1a25 100644
--- a/src/engine/shared/console.cpp
+++ b/src/engine/shared/console.cpp
@@ -157,11 +157,15 @@ void CConsole::RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUse
 	m_pPrintCallbackUserdata = pUserData;
 }
 
-void CConsole::Print(const char *pStr)
+void CConsole::Print(int Level, const char *pFrom, const char *pStr)
 {
-	dbg_msg("console" ,"%s", pStr);
-	if (m_pfnPrintCallback)
-		m_pfnPrintCallback(pStr, m_pPrintCallbackUserdata);
+	dbg_msg(pFrom ,"%s", pStr);
+	if (Level <= g_Config.m_ConsoleOutputLevel && m_pfnPrintCallback)
+	{
+		char aBuf[1024];
+		str_format(aBuf, sizeof(aBuf), "[%s]: %s", pFrom, pStr);
+		m_pfnPrintCallback(aBuf, m_pPrintCallbackUserdata);
+	}
 }
 
 void CConsole::ExecuteLineStroked(int Stroke, const char *pStr)
@@ -218,7 +222,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr)
 				{
 					char aBuf[256];
 					str_format(aBuf, sizeof(aBuf), "Invalid arguments... Usage: %s %s", pCommand->m_pName, pCommand->m_pParams);
-					Print(aBuf);
+					Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf);
 				}
 				else if(m_StoreCommands && pCommand->m_Flags&CFGFLAG_STORE)
 				{
@@ -234,7 +238,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr)
 		{
 			char aBuf[256];
 			str_format(aBuf, sizeof(aBuf), "No such command: %s.", pResult->m_pCommand);
-			Print(aBuf);
+			Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf);
 		}
 		
 		pStr = pNextPart;
@@ -298,12 +302,14 @@ void CConsole::ExecuteFile(const char *pFilename)
 	// exec the file
 	IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_READ);
 	
+	char aBuf[256];
 	if(File)
 	{
 		char *pLine;
 		CLineReader lr;
 		
-		dbg_msg("console", "executing '%s'", pFilename);
+		str_format(aBuf, sizeof(aBuf), "executing '%s'", pFilename);
+		Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", aBuf);
 		lr.Init(File);
 
 		while((pLine = lr.Get()))
@@ -312,14 +318,17 @@ void CConsole::ExecuteFile(const char *pFilename)
 		io_close(File);
 	}
 	else
-		dbg_msg("console", "failed to open '%s'", pFilename);
+	{
+		str_format(aBuf, sizeof(aBuf), "failed to open '%s'", pFilename);
+		Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", aBuf);
+	}
 	
 	m_pFirstExec = pPrev;
 }
 
 void CConsole::Con_Echo(IResult *pResult, void *pUserData)
 {
-	((CConsole*)pUserData)->Print(pResult->GetString(0));
+	((CConsole*)pUserData)->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Console", pResult->GetString(0));
 }
 
 void CConsole::Con_Exec(IResult *pResult, void *pUserData)
@@ -365,7 +374,7 @@ static void IntVariableCommand(IConsole::IResult *pResult, void *pUserData)
 	{
 		char aBuf[1024];
 		str_format(aBuf, sizeof(aBuf), "Value: %d", *(pData->m_pVariable));
-		pData->m_pConsole->Print(aBuf);
+		pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Console", aBuf);
 	}
 }
 
@@ -379,7 +388,7 @@ static void StrVariableCommand(IConsole::IResult *pResult, void *pUserData)
 	{
 		char aBuf[1024];
 		str_format(aBuf, sizeof(aBuf), "Value: %s", pData->m_pStr);
-		pData->m_pConsole->Print(aBuf);
+		pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Console", aBuf);
 	}
 }
 
@@ -466,7 +475,9 @@ void CConsole::Chain(const char *pName, FChainCommandCallback pfnChainFunc, void
 	
 	if(!pCommand)
 	{
-		dbg_msg("console", "failed to chain '%s'", pName);
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "failed to chain '%s'", pName);
+		Print(IConsole::OUTPUT_LEVEL_DEBUG, "console", aBuf);
 		return;
 	}
 	
diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h
index 9c127ae0..87df6dea 100644
--- a/src/engine/shared/console.h
+++ b/src/engine/shared/console.h
@@ -123,7 +123,7 @@ public:
 	virtual void ExecuteFile(const char *pFilename);
 
 	virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData);
-	virtual void Print(const char *pStr);
+	virtual void Print(int Level, const char *pFrom, const char *pStr);
 };
 
 #endif
diff --git a/src/engine/shared/demorec.cpp b/src/engine/shared/demorec.cpp
index 6c2ba07d..23da2478 100644
--- a/src/engine/shared/demorec.cpp
+++ b/src/engine/shared/demorec.cpp
@@ -1,4 +1,5 @@
 #include <base/system.h>
+#include <engine/console.h>
 #include <engine/shared/protocol.h>
 #include <engine/storage.h>
 #include "demorec.h"
@@ -20,17 +21,20 @@ CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta)
 //static IOHANDLE m_File = 0;
 
 // Record
-int CDemoRecorder::Start(class IStorage *pStorage, const char *pFilename, const char *pNetVersion, const char *pMap, int Crc, const char *pType)
+int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetVersion, const char *pMap, int Crc, const char *pType)
 {
 	CDemoHeader Header;
 	if(m_File)
 		return -1;
 
+	m_pConsole = pConsole;
 	m_File = pStorage->OpenFile(pFilename, IOFLAG_WRITE);
 	
 	if(!m_File)
 	{
-		dbg_msg("demorec/record", "Unable to open '%s' for recording", pFilename);
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "Unable to open '%s' for recording", pFilename);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf);
 		return -1;
 	}
 	
@@ -49,7 +53,9 @@ int CDemoRecorder::Start(class IStorage *pStorage, const char *pFilename, const
 	m_LastKeyFrame = -1;
 	m_LastTickMarker = -1;
 	
-	dbg_msg("demorec/record", "Recording to '%s'", pFilename);
+	char aBuf[256];
+	str_format(aBuf, sizeof(aBuf), "Recording to '%s'", pFilename);
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf);
 	return 0;
 }
 
@@ -193,7 +199,7 @@ int CDemoRecorder::Stop()
 	if(!m_File)
 		return -1;
 		
-	dbg_msg("demorec/record", "Stopped recording");
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Stopped recording");
 	io_close(m_File);
 	m_File = 0;
 	return 0;
@@ -348,7 +354,7 @@ void CDemoPlayer::DoTick()
 		if(ReadChunkHeader(&ChunkType, &ChunkSize, &ChunkTick))
 		{
 			// stop on error or eof
-			dbg_msg("demorec", "end of file");
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "demo_player", "end of file");
 			Pause();
 			break;
 		}
@@ -359,7 +365,7 @@ void CDemoPlayer::DoTick()
 			if(io_read(m_File, aCompresseddata, ChunkSize) != (unsigned)ChunkSize)
 			{
 				// stop on error or eof
-				dbg_msg("demorec", "error reading chunk");
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "demo_player", "error reading chunk");
 				Stop();
 				break;
 			}
@@ -368,7 +374,7 @@ void CDemoPlayer::DoTick()
 			if(DataSize < 0)
 			{
 				// stop on error or eof
-				dbg_msg("demorec", "error during network decompression");
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "demo_player", "error during network decompression");
 				Stop();
 				break;
 			}
@@ -377,7 +383,7 @@ void CDemoPlayer::DoTick()
 
 			if(DataSize < 0)
 			{
-				dbg_msg("demorec", "error during intpack decompression");
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "demo_player", "error during intpack decompression");
 				Stop();
 				break;
 			}
@@ -401,7 +407,11 @@ void CDemoPlayer::DoTick()
 				mem_copy(m_aLastSnapshotData, aNewsnap, DataSize);
 			}
 			else
-				dbg_msg("demorec", "error duing unpacking of delta, err=%d", DataSize);
+			{
+				char aBuf[256];
+				str_format(aBuf, sizeof(aBuf), "error during unpacking of delta, err=%d", DataSize);
+				m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "demo_player", aBuf);
+			}
 		}
 		else if(ChunkType == CHUNKTYPE_SNAPSHOT)
 		{
@@ -452,12 +462,15 @@ void CDemoPlayer::Unpause()
 	}
 }
 
-int CDemoPlayer::Load(class IStorage *pStorage, const char *pFilename)
+int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename)
 {
+	m_pConsole = pConsole;
 	m_File = pStorage->OpenFile(pFilename, IOFLAG_READ);
 	if(!m_File)
 	{
-		dbg_msg("demorec/playback", "could not open '%s'", pFilename);
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "could not open '%s'", pFilename);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_player", aBuf);
 		return -1;
 	}
 	
@@ -477,7 +490,9 @@ int CDemoPlayer::Load(class IStorage *pStorage, const char *pFilename)
 	io_read(m_File, &m_Info.m_Header, sizeof(m_Info.m_Header));
 	if(mem_comp(m_Info.m_Header.m_aMarker, gs_aHeaderMarker, sizeof(gs_aHeaderMarker)) != 0)
 	{
-		dbg_msg("demorec/playback", "'%s' is not a demo file", pFilename);
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "'%s' is not a demo file", pFilename);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_player", aBuf);
 		io_close(m_File);
 		m_File = 0;
 		return -1;
@@ -599,8 +614,10 @@ int CDemoPlayer::Update()
 		if(m_Info.m_Info.m_CurrentTick == m_Info.m_PreviousTick ||
 			m_Info.m_Info.m_CurrentTick == m_Info.m_NextTick)
 		{
-			dbg_msg("demorec/playback", "tick error prev=%d cur=%d next=%d",
+			char aBuf[256];
+			str_format(aBuf, sizeof(aBuf), "tick error prev=%d cur=%d next=%d",
 				m_Info.m_PreviousTick, m_Info.m_Info.m_CurrentTick, m_Info.m_NextTick);
+			m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "demo_player", aBuf);
 		}
 	}
 	
@@ -612,7 +629,7 @@ int CDemoPlayer::Stop()
 	if(!m_File)
 		return -1;
 		
-	dbg_msg("demorec/playback", "Stopped playback");
+	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_player", "Stopped playback");
 	io_close(m_File);
 	m_File = 0;
 	mem_free(m_pKeyFrames);
diff --git a/src/engine/shared/demorec.h b/src/engine/shared/demorec.h
index 294a088b..cdf46e99 100644
--- a/src/engine/shared/demorec.h
+++ b/src/engine/shared/demorec.h
@@ -15,6 +15,7 @@ struct CDemoHeader
 
 class CDemoRecorder : public IDemoRecorder
 {
+	class IConsole *m_pConsole;
 	IOHANDLE m_File;
 	int m_LastTickMarker;
 	int m_LastKeyFrame;
@@ -26,7 +27,7 @@ class CDemoRecorder : public IDemoRecorder
 public:
 	CDemoRecorder(class CSnapshotDelta *pSnapshotDelta);
 	
-	int Start(class IStorage *pStorage, const char *pFilename, const char *pNetversion, const char *pMap, int MapCrc, const char *pType);
+	int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, int MapCrc, const char *pType);
 	int Stop();
 
 	void RecordSnapshot(int Tick, const void *pData, int Size);
@@ -80,6 +81,7 @@ private:
 		CKeyFrameSearch *m_pNext;
 	};	
 
+	class IConsole *m_pConsole;
 	IOHANDLE m_File;
 	CKeyFrame *m_pKeyFrames;
 
@@ -99,7 +101,7 @@ public:
 	
 	void SetListner(IListner *pListner);
 		
-	int Load(class IStorage *pStorage, const char *pFilename);
+	int Load(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename);
 	int Play();
 	void Pause();
 	void Unpause();
diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h
index 7de534a4..a2232320 100644
--- a/src/engine/shared/network.h
+++ b/src/engine/shared/network.h
@@ -79,7 +79,7 @@ enum
 };
 
 
-typedef int (*NETFUNC_DELCLIENT)(int ClientID, void *pUser);
+typedef int (*NETFUNC_DELCLIENT)(int ClientID, const char* pReason, void *pUser);
 typedef int (*NETFUNC_NEWCLIENT)(int ClientID, void *pUser);
 
 struct CNetChunk
diff --git a/src/engine/shared/network_client.cpp b/src/engine/shared/network_client.cpp
index f7859c0a..57ed08a8 100644
--- a/src/engine/shared/network_client.cpp
+++ b/src/engine/shared/network_client.cpp
@@ -21,7 +21,7 @@ int CNetClient::Close()
 
 int CNetClient::Disconnect(const char *pReason)
 {
-	dbg_msg("netclient", "disconnected. reason=\"%s\"", pReason);
+	//dbg_msg("netclient", "disconnected. reason=\"%s\"", pReason);
 	m_Connection.Disconnect(pReason);
 	return 0;
 }
diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp
index 2d30a7d1..ed714365 100644
--- a/src/engine/shared/network_server.cpp
+++ b/src/engine/shared/network_server.cpp
@@ -79,16 +79,15 @@ int CNetServer::Drop(int ClientID, const char *pReason)
 	// TODO: insert lots of checks here
 	NETADDR Addr = ClientAddr(ClientID);
 
-	dbg_msg("net_server", "client dropped. cid=%d ip=%d.%d.%d.%d reason=\"%s\"",
+	/*dbg_msg("net_server", "client dropped. cid=%d ip=%d.%d.%d.%d reason=\"%s\"",
 		ClientID,
 		Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3],
 		pReason
-		);
+		);*/
+	if(m_pfnDelClient)
+		m_pfnDelClient(ClientID, pReason, m_UserPtr);
 		
 	m_aSlots[ClientID].m_Connection.Disconnect(pReason);
-
-	if(m_pfnDelClient)
-		m_pfnDelClient(ClientID, m_UserPtr);
 		
 	return 0;
 }