← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/log_messages into lp:widelands

 

cghislai has proposed merging lp:~widelands-dev/widelands/log_messages into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1206441 in widelands: "Autosave leads to crash on replays"
  https://bugs.launchpad.net/widelands/+bug/1206441

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/log_messages/+merge/177712

This is a rework of the use of chat messages to log informationnal messages.

- A new LogMessage struct was created appart of ChatMessage.
- The interactivegamebase is a NoteSender of LogMessage. His log_message() method will send the message to all receivers. The ChatOverlay has also moved in a protected field in this class. This was required so it is initialized before the toolbar box, so that chat messages are displayed below it.
- The ChatOverlay receives ChatMessage as well as LogMessage notes. It keeps the log message in a local vector. It displays both chat and logs mixed and in chronological order. It also uses the new renderer to display them.
- All send_local methods are removed, and it was quite a hack anyway. Several classes do not extend ChatProvider anymore.

Some things to review:
- bug 1206712 can be triggered quite easily using this branch.
- I didn't manage to draw a semi-transparent background below chat messages, it doesn't seem to work as expected?
-- 
https://code.launchpad.net/~widelands-dev/widelands/log_messages/+merge/177712
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/log_messages into lp:widelands.
=== modified file 'src/chat.cc'
--- src/chat.cc	2013-07-26 05:57:03 +0000
+++ src/chat.cc	2013-07-30 22:51:28 +0000
@@ -23,7 +23,7 @@
 
 using namespace Widelands;
 
-std::string ChatMessage::toPrintable() const
+std::string ChatMessage::toOldRichText() const
 {
 	std::string message = "<p font-color=#33ff33 font-size=9>";
 
@@ -120,6 +120,105 @@
 	return message + "<br></p>";
 }
 
+std::string ChatMessage::toPrintable() const
+{
+	std::string message = "<p><font color=33ff33 size=9>";
+
+	// Escape richtext characters
+	// The goal of this code is two-fold:
+	//  1. Assuming an honest game host, we want to prevent the ability of
+	//     clients to use richtext.
+	//  2. Assuming a malicious host or meta server, we want to reduce the
+	//     likelihood that a bug in the richtext renderer can be exploited,
+	//     by restricting the set of allowed richtext commands.
+	//     Most notably, images are not allowed in richtext at all.
+	//
+	// Note that we do want host and meta server to send some richtext code,
+	// as the ability to send formatted commands is nice for the usability
+	// of meta server and dedicated servers, so we're treading a bit of a
+	// fine line here.
+	std::string sanitized;
+	for (std::string::size_type pos = 0; pos < msg.size(); ++pos) {
+		if (msg[pos] == '<') {
+			if (playern < 0) {
+				static const std::string good1 = "</p><p";
+				static const std::string good2 = "<br>";
+				if (!msg.compare(pos, good1.size(), good1)) {
+					std::string::size_type nextclose = msg.find('>', pos + good1.size());
+					if
+						(nextclose != std::string::npos &&
+						(nextclose == pos + good1.size() || msg[pos + good1.size()] == ' '))
+					{
+						sanitized += good1;
+						pos += good1.size() - 1;
+						continue;
+					}
+				} else if (!msg.compare(pos, good2.size(), good2)) {
+					sanitized += good2;
+					pos += good2.size() - 1;
+					continue;
+				}
+			}
+
+			sanitized += "&lt;";
+		} else {
+			sanitized += msg[pos];
+		}
+	}
+
+	// time calculation
+	char ts[13];
+	strftime(ts, sizeof(ts), "[%H:%M] ", localtime(&time));
+	message += ts;
+
+	message += "</font><font size=14 face=DejaVuSerif color=";
+	message += color();
+
+	if (recipient.size() && sender.size()) {
+		// Personal message handling
+		if (sanitized.compare(0, 3, "/me")) {
+			message += " bold=1>";
+			message += sender;
+			message += " @ ";
+			message += recipient;
+			message += ":</font><font size=14 face=DejaVuSerif shadow=1 color=eeeeee> ";
+			message += sanitized;
+		} else {
+			message += ">@";
+			message += recipient;
+			message += " \\> </font><font size=14";
+			message += " face=DejaVuSerif color=";
+			message += color();
+			message += " italic=1 shadow=1> ";
+			message += sender;
+			message += sanitized.substr(3);
+		}
+	} else {
+		// Normal messages handling
+		if (not sanitized.compare(0, 3, "/me")) {
+			message += " italic=1>-\\> ";
+			if (sender.size())
+				message += sender;
+			else
+				message += "***";
+			message += sanitized.substr(3);
+		} else if (sender.size()) {
+			message += " bold=1>";
+			message += sender;
+			message += ":</font><font size=14 face=DejaVuSerif shadow=1 color=eeeeee> ";
+			message += sanitized;
+		} else {
+			message += " bold=1>*** ";
+			message += sanitized;
+		}
+	}
+
+	// return the formated message
+	return message + "</font><br></p>";
+}
+
+
+
 std::string ChatMessage::toPlainString() const
 {
 	return sender + ": " + msg;

=== modified file 'src/chat.h'
--- src/chat.h	2013-07-26 19:16:51 +0000
+++ src/chat.h	2013-07-30 22:51:28 +0000
@@ -73,6 +73,7 @@
 	 * \return a richtext string that can be displayed to the user.
 	 */
 	std::string toPrintable() const;
+	std::string toOldRichText() const;
 
 	/**
 	 * \return a plain string containing the sender + message.
@@ -106,12 +107,6 @@
 	virtual void send(const std::string &) = 0;
 
 	/**
-	 * Sends the given message to the local player only
-	 * This may be used to display useful log messages.
-	 */
-	virtual void send_local(const std::string &) = 0;
-
-	/**
 	 * \return a (chronological) list of received chat messages.
 	 * This list need not be stable or monotonic. In other words,
 	 * subsequent calls to this functions may return a smaller or

=== modified file 'src/debugconsole.cc'
--- src/debugconsole.cc	2013-07-26 19:16:51 +0000
+++ src/debugconsole.cc	2013-07-30 22:51:28 +0000
@@ -86,10 +86,6 @@
 		it->second(arg);
 	}
 
-	void send_local(const std::string& msg) {
-		send(msg);
-	}
-
 	const std::vector<ChatMessage> & getMessages() const
 	{
 		return messages;

=== modified file 'src/gamecontroller.cc'
--- src/gamecontroller.cc	2013-07-26 19:16:51 +0000
+++ src/gamecontroller.cc	2013-07-30 22:51:28 +0000
@@ -19,16 +19,14 @@
 
 #include "gamecontroller.h"
 
-#include "chat.h"
 #include "computer_player.h"
 #include "logic/game.h"
 #include "logic/player.h"
 #include "logic/playercommand.h"
 #include "profile/profile.h"
 #include "wlapplication.h"
-#include "wui/interactive_player.h"
 
-struct SinglePlayerGameController : public GameController, public ChatProvider {
+struct SinglePlayerGameController : public GameController {
 	SinglePlayerGameController
 		(Widelands::Game &, bool useai, Widelands::Player_Number local);
 	~SinglePlayerGameController();
@@ -44,10 +42,6 @@
 	bool isPaused();
 	void setPaused(bool paused);
 
-	// Chat provider implementation
-	void send(const std::string & msg);
-	void send_local(const std::string & msg);
-	const std::vector<ChatMessage> & getMessages() const;
 private:
 	Widelands::Game & m_game;
 	bool m_useai;
@@ -58,15 +52,13 @@
 	uint32_t m_player_cmdserial;
 	Widelands::Player_Number m_local;
 	std::vector<Computer_Player *> m_computerplayers;
-	std::vector<ChatMessage> m_chatmessages;
 };
 
 SinglePlayerGameController::SinglePlayerGameController
 	(Widelands::Game        &       game,
 	 bool                     const useai,
 	 Widelands::Player_Number const local)
-	: ChatProvider(),
-	m_game            (game),
+	: m_game          (game),
 	m_useai           (useai),
 	m_lastframe       (WLApplication::get()->get_time()),
 	m_time            (m_game.get_gametime()),
@@ -163,31 +155,11 @@
 	m_paused = paused;
 }
 
-void SinglePlayerGameController::send_local(const std::string& msg)
-{
-	ChatMessage c;
-	c.msg = msg;
-	c.time = time(0);
-	m_chatmessages.push_back(c);
-	ChatProvider::send(c);
-}
-
-void SinglePlayerGameController::send(const std::string& /* msg */)
-{
-	log("SinglePlayerGameController:: Cannot send chat messages in single player game!");
-}
-
-const std::vector< ChatMessage >& SinglePlayerGameController::getMessages() const
-{
-	return m_chatmessages;
-}
-
 GameController * GameController::createSinglePlayer
 	(Widelands::Game        &       game,
 	 bool                     const cpls,
 	 Widelands::Player_Number const local)
 {
 	SinglePlayerGameController* spgc =  new SinglePlayerGameController(game, cpls, local);
-	game.get_ipl()->set_chat_provider(*spgc);
 	return spgc;
 }

=== modified file 'src/log.h'
--- src/log.h	2013-07-18 06:31:11 +0000
+++ src/log.h	2013-07-30 22:51:28 +0000
@@ -53,5 +53,4 @@
 
 extern bool g_verbose;
 
-
 #endif

=== modified file 'src/logic/notification.h'
--- src/logic/notification.h	2013-07-26 20:19:36 +0000
+++ src/logic/notification.h	2013-07-30 22:51:28 +0000
@@ -55,7 +55,7 @@
 	}
 
 protected:
-	void send(const T & note) {
+	void send(const T & note) const {
 		container_iterate_const(Links, m_links, i)
 			(*i.current)->receive(note);
 	}

=== modified file 'src/network/internet_gaming.cc'
--- src/network/internet_gaming.cc	2013-07-26 20:19:36 +0000
+++ src/network/internet_gaming.cc	2013-07-30 22:51:28 +0000
@@ -768,15 +768,6 @@
 	s.send(m_sock);
 }
 
-void InternetGaming::send_local(const std::string& msg)
-{
-	ChatMessage c;
-	c.msg = msg;
-	c.time = time(0);
-	messages.push_back(c);
-	ChatProvider::send(c);
-}
-
 /**
  * \returns the boolean value of a string received from the metaserver.
  * If conversion fails, it throws a \ref warning

=== modified file 'src/network/internet_gaming.h'
--- src/network/internet_gaming.h	2013-07-26 20:19:36 +0000
+++ src/network/internet_gaming.h	2013-07-30 22:51:28 +0000
@@ -113,9 +113,6 @@
 	// ChatProvider: sends a message via the metaserver.
 	void send(const std::string &);
 
-	// ChatProvider: sends local messages
-	void send_local(const std::string &);
-
 	/// ChatProvider: adds the message to the message list and calls parent.
 	void receive(const ChatMessage & msg) {messages.push_back(msg); ChatProvider::send(msg);}
 

=== modified file 'src/network/netclient.cc'
--- src/network/netclient.cc	2013-07-26 20:19:36 +0000
+++ src/network/netclient.cc	2013-07-30 22:51:28 +0000
@@ -623,15 +623,6 @@
 	s.send(d->sock);
 }
 
-void NetClient::send_local(const std::string& msg)
-{
-	ChatMessage c;
-	c.msg = msg;
-	c.time = time(0);
-	d->chatmessages.push_back(c);
-	ChatProvider::send(c);
-}
-
 const std::vector<ChatMessage> & NetClient::getMessages() const
 {
 	return d->chatmessages;

=== modified file 'src/network/netclient.h'
--- src/network/netclient.h	2013-07-26 20:19:36 +0000
+++ src/network/netclient.h	2013-07-30 22:51:28 +0000
@@ -92,7 +92,6 @@
 
 	// ChatProvider interface
 	void send(const std::string & msg);
-	void send_local(const std::string & msg);
 	const std::vector<ChatMessage> & getMessages() const;
 
 private:

=== modified file 'src/network/nethost.cc'
--- src/network/nethost.cc	2013-07-26 20:19:36 +0000
+++ src/network/nethost.cc	2013-07-30 22:51:28 +0000
@@ -497,13 +497,6 @@
 		h->send(c);
 	}
 
-	void send_local(const std::string & msg) {
-		ChatMessage c;
-		c.time = time(0);
-		c.msg = msg;
-		ChatProvider::send(c);
-	}
-
 	const std::vector<ChatMessage> & getMessages() const {
 		return messages;
 	}

=== modified file 'src/save_handler.cc'
--- src/save_handler.cc	2013-07-26 05:57:03 +0000
+++ src/save_handler.cc	2013-07-30 22:51:28 +0000
@@ -68,8 +68,7 @@
 
 	// TODO: defer saving to next tick so that this message is shown
 	// before the actual save, or put the saving logic in another thread
-	game.get_ipl()->get_chat_provider()->send_local
-		(_("Saving game..."));
+	game.get_ibase()->log_message(_("Saving game..."));
 
 	// save the game
 	const std::string complete_filename = create_file_name(get_base_dir(), filename);
@@ -88,8 +87,7 @@
 	std::string error;
 	if (!save_game(game, complete_filename, &error)) {
 		log("Autosave: ERROR! - %s\n", error.c_str());
-		game.get_ipl()->get_chat_provider()->send_local
-			(_("Saving failed!"));
+		game.get_ibase()->log_message(_("Saving failed!"));
 
 		// if backup file was created, move it back
 		if (backup_filename.length() > 0) {
@@ -108,8 +106,7 @@
 	}
 
 	log("Autosave: save took %d ms\n", m_last_saved_time - realtime);
-	game.get_ipl()->get_chat_provider()->send_local
-		(_("Game saved"));
+	game.get_ibase()->log_message(_("Game saved"));
 }
 
 /**

=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc	2013-07-30 08:58:02 +0000
+++ src/wlapplication.cc	2013-07-30 22:51:28 +0000
@@ -84,12 +84,12 @@
 #include "wui/interactive_player.h"
 #include "wui/interactive_spectator.h"
 
-#ifndef NDEBUG
+#ifndef NDEBUG
 #ifndef _WIN32
 int32_t WLApplication::pid_me   = 0;
 int32_t WLApplication::pid_peer = 0;
 volatile int32_t WLApplication::may_run = 0;
-#endif
+#endif
 #endif
 
 #define MINIMUM_DISK_SPACE 250000000lu

=== modified file 'src/wui/chatoverlay.cc'
--- src/wui/chatoverlay.cc	2013-07-26 20:19:36 +0000
+++ src/wui/chatoverlay.cc	2013-07-30 22:51:28 +0000
@@ -20,8 +20,9 @@
 #include "wui/chatoverlay.h"
 
 #include "chat.h"
+#include "graphic/font_handler1.h"
 #include "graphic/rendertarget.h"
-#include "graphic/richtext.h"
+#include "logmessage.h"
 #include "profile/profile.h"
 
 /**
@@ -30,7 +31,8 @@
 static const int32_t CHAT_DISPLAY_TIME = 10;
 static const uint32_t MARGIN = 2;
 
-struct ChatOverlay::Impl : Widelands::NoteReceiver<ChatMessage> {
+struct ChatOverlay::Impl : Widelands::NoteReceiver<ChatMessage>,
+	Widelands::NoteReceiver<LogMessage> {
 	bool transparent;
 	ChatProvider * chat;
 	bool havemessages;
@@ -39,12 +41,16 @@
 	time_t oldest;
 
 	/// Layouted message list
-	UI::RichText rt;
+	std::string all_text;
+
+	/// Log messages
+	std::vector<LogMessage> log_messages;
 
 	Impl() : transparent(false), chat(0), havemessages(false), oldest(0) {}
 
 	void recompute();
 	virtual void receive(const ChatMessage & note);
+	virtual void receive(const LogMessage & note);
 };
 
 ChatOverlay::ChatOverlay
@@ -56,8 +62,6 @@
 	m->transparent = s.get_bool("transparent_chat", true);
 
 	set_think(true);
-	m->rt.set_width(w - 2 * MARGIN);
-	m->rt.set_background_color(RGBColor(50, 50, 50));
 }
 
 ChatOverlay::~ChatOverlay()
@@ -67,10 +71,20 @@
 void ChatOverlay::setChatProvider(ChatProvider & chat)
 {
 	m->chat = &chat;
-	m->connect(chat);
+	Widelands::NoteReceiver<ChatMessage>* cmr
+		= dynamic_cast<Widelands::NoteReceiver<ChatMessage>*>(m.get());
+	cmr->connect(chat);
 	m->recompute();
 }
 
+void ChatOverlay::setLogProvider(Widelands::NoteSender<LogMessage>& log_sender)
+{
+	Widelands::NoteReceiver<LogMessage>* lmr
+		= dynamic_cast<Widelands::NoteReceiver<LogMessage>*>(m.get());
+	lmr->connect(log_sender);
+}
+
+
 /**
  * Check for message expiry.
  */
@@ -90,6 +104,13 @@
 	recompute();
 }
 
+void ChatOverlay::Impl::receive(const LogMessage& note)
+{
+	log_messages.push_back(note);
+	recompute();
+}
+
+
 /**
  * Recompute the chat message display.
  */
@@ -99,18 +120,51 @@
 
 	havemessages = false;
 
-	const std::vector<ChatMessage> & msgs = chat->getMessages();
-	uint32_t idx = msgs.size();
+	// Parse the chat message list as well as the log message list
+	// and display them in chronological order
+	int32_t chat_idx = chat != nullptr ? chat->getMessages().size() - 1 : -1;
+	int32_t log_idx = log_messages.empty() ? -1 : log_messages.size() - 1;
+	int32_t msg_time = now;
 	std::string richtext;
-	while (idx && now - msgs[idx - 1].time <= CHAT_DISPLAY_TIME) {
-		richtext = msgs[idx - 1].toPrintable() + richtext;
+
+	while ((chat_idx >= 0 || log_idx >= 0) && now - msg_time < CHAT_DISPLAY_TIME) {
+		if
+			(chat_idx < 0  ||
+				(log_idx >= 0 && chat->getMessages()[chat_idx].time < log_messages[log_idx].time))
+		{
+			// Log message is more recent
+			msg_time = log_messages[log_idx].time;
+			// Do some richtext formatting here
+			richtext = "<p><font face=DejaVuSerif size=14 color=dddddd bold=1>"
+				+ log_messages[log_idx].msg + "<br></font></p>" + richtext;
+			log_idx--;
+		} else if
+			(log_idx < 0 ||
+				(chat_idx >= 0 && chat->getMessages()[chat_idx].time >= log_messages[log_idx].time))
+		{
+			// Chat message is more recent
+			msg_time = chat->getMessages()[chat_idx].time;
+			richtext = chat->getMessages()[chat_idx].toPrintable()
+				+ richtext;
+			chat_idx--;
+		} else {
+			// Shoudn't happen
+			assert(false);
+		}
 		havemessages = true;
-		oldest = msgs[idx - 1].time;
-		idx--;
-	}
-
-	if (havemessages)
-		rt.parse("<rt>" + richtext + "</rt>");
+		oldest = msg_time;
+	}
+
+	// Parse log messages to clear old ones
+	msg_time = log_messages.front().time;
+	while (now - msg_time > CHAT_DISPLAY_TIME) {
+		log_messages.erase(log_messages.begin());
+		msg_time = log_messages.front().time;
+	}
+
+	if (havemessages) {
+		all_text = "<rt>" + richtext + "</rt>";
+	}
 }
 
 void ChatOverlay::draw(RenderTarget & dst)
@@ -118,8 +172,17 @@
 	if (!m->havemessages)
 		return;
 
-	int32_t height = m->rt.height();
+	const Image* im = UI::g_fh1->render(m->all_text, get_w());
+	// Background
+	int32_t height = im->height() > get_h() ? get_h() : im->height();
 	int32_t top = get_h() - height - 2 * MARGIN;
 
-	m->rt.draw(dst, Point(MARGIN, top + MARGIN), !m->transparent);
+	//FIXME: alpha channel not respected
+	if (!m->transparent) {
+		Rect rect(0, top, im->width(), height);
+		dst.fill_rect(rect, RGBAColor(50, 50, 50, 128));
+	}
+
+	Point pt(0, top);
+	dst.blit(pt, im);
 }

=== modified file 'src/wui/chatoverlay.h'
--- src/wui/chatoverlay.h	2013-07-21 08:07:18 +0000
+++ src/wui/chatoverlay.h	2013-07-30 22:51:28 +0000
@@ -20,9 +20,11 @@
 #ifndef CHATOVERLAY_H
 #define CHATOVERLAY_H
 
+#include "logic/notification.h"
 #include "ui_basic/panel.h"
 
 struct ChatProvider;
+struct LogMessage;
 
 /**
  * The overlay that displays all new chat messages for some timeout on the main window.
@@ -34,6 +36,7 @@
 	~ChatOverlay();
 
 	void setChatProvider(ChatProvider &);
+	void setLogProvider(Widelands::NoteSender<LogMessage> &);
 	virtual void draw(RenderTarget &);
 	virtual void think();
 

=== modified file 'src/wui/gamechatpanel.cc'
--- src/wui/gamechatpanel.cc	2013-07-26 20:19:36 +0000
+++ src/wui/gamechatpanel.cc	2013-07-30 22:51:28 +0000
@@ -52,7 +52,7 @@
 
 	std::string str = "<rt>";
 	for (uint32_t i = 0; i < msgs.size(); ++i) {
-		str += msgs[i].toPrintable();
+		str += msgs[i].toOldRichText();
 		str += '\n';
 	}
 	str += "</rt>";

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2013-07-26 20:19:36 +0000
+++ src/wui/interactive_base.cc	2013-07-30 22:51:28 +0000
@@ -76,6 +76,7 @@
 	(Editor_Game_Base & the_egbase, Section & global_s)
 	:
 	Map_View(0, 0, 0, global_s.get_int("xres", XRES), global_s.get_int("yres", YRES), *this),
+	NoteSender<LogMessage>(),
 	m_show_workarea_preview(global_s.get_bool("workareapreview", true)),
 	m
 		(new InteractiveBaseInternals
@@ -93,6 +94,8 @@
 	m_road_buildhelp_overlay_jobid(Overlay_Manager::Job_Id::Null()),
 	m_buildroad                   (0),
 	m_road_build_player           (0),
+	// Initialize chatoveraly before the toolbar so it is below
+	m_chatOverlay                 (new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25)),
 	m_toolbar                     (this, 0, 0, UI::Box::Horizontal),
 	m_label_speed_shadow
 		(this, get_w() - 1, 0, std::string(), UI::Align_TopRight),
@@ -115,6 +118,8 @@
 	set_dock_windows_to_edges
 		(global_s.get_bool("dock_windows_to_edges", false));
 
+	m_chatOverlay->setLogProvider(*this);
+
 	//  Switch to the new graphics system now, if necessary.
 	WLApplication::get()->refresh_graphics();
 
@@ -761,6 +766,16 @@
 	return m_buildroad->get_end();
 }
 
+void Interactive_Base::log_message(const std::string& message) const
+{
+	// Send to linked receivers
+	LogMessage lm;
+	lm.msg = message;
+	lm.time = time(nullptr);
+	send(lm);
+}
+
+
 
 /*
 ===============

=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h	2013-07-26 20:19:36 +0000
+++ src/wui/interactive_base.h	2013-07-30 22:51:28 +0000
@@ -25,6 +25,9 @@
 #include "debugconsole.h"
 #include "logic/editor_game_base.h"
 #include "logic/map.h"
+#include "logic/notification.h"
+#include "logmessage.h"
+#include "wui/chatoverlay.h"
 #include "wui/mapview.h"
 #include "wui/overlay_manager.h"
 #include "ui_basic/box.h"
@@ -39,7 +42,8 @@
  * This is used to represent the code that Interactive_Player and
  * Editor_Interactive share.
  */
-struct Interactive_Base : public Map_View, public DebugConsole::Handler {
+struct Interactive_Base : public Map_View, public DebugConsole::Handler,
+	public Widelands::NoteSender<LogMessage> {
 
 	friend class Sound_Handler;
 
@@ -111,6 +115,13 @@
 
 	virtual void cleanup_for_load() {};
 
+	/**
+	 * Log a message to be displayed on screen
+	 */
+	void log_message(const std::string& message) const;
+	void log_message(const char* message) const {
+		log_message(std::string(message));
+	}
 private:
 	void roadb_add_overlay   ();
 	void roadb_remove_overlay();
@@ -169,6 +180,7 @@
 		m_toolbar.set_pos
 			(Point((get_inner_w() - m_toolbar.get_w()) >> 1, get_inner_h() - 34));
 	}
+	ChatOverlay     * m_chatOverlay;
 	UI::Box           m_toolbar;
 
 

=== modified file 'src/wui/interactive_gamebase.cc'
--- src/wui/interactive_gamebase.cc	2013-07-26 20:19:36 +0000
+++ src/wui/interactive_gamebase.cc	2013-07-30 22:51:28 +0000
@@ -25,7 +25,6 @@
 #include "logic/ship.h"
 #include "profile/profile.h"
 #include "upcast.h"
-#include "wui/chatoverlay.h"
 
 Interactive_GameBase::Interactive_GameBase
 	(Widelands::Game & _game, Section & global_s,
@@ -33,7 +32,6 @@
 	:
 	Interactive_Base(_game, global_s),
 	m_chatProvider(0),
-	m_chatOverlay(0),
 	m_building_census_format
 		(global_s.get_string("building_census_format",       "%N")),
 	m_building_statistics_format

=== modified file 'src/wui/interactive_gamebase.h'
--- src/wui/interactive_gamebase.h	2013-07-26 20:19:36 +0000
+++ src/wui/interactive_gamebase.h	2013-07-30 22:51:28 +0000
@@ -24,7 +24,6 @@
 #include "wui/interactive_base.h"
 #include "logic/game.h"
 
-struct ChatOverlay;
 struct ChatProvider;
 
 enum PlayerType {NONE, OBSERVER, PLAYING, VICTORIOUS, DEFEATED};
@@ -82,7 +81,6 @@
 protected:
 	Game_Main_Menu_Windows m_mainm_windows;
 	ChatProvider           * m_chatProvider;
-	ChatOverlay            * m_chatOverlay;
 	std::string              m_building_census_format;
 	std::string              m_building_statistics_format;
 	std::string              m_building_tooltip_format;

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2013-07-26 20:19:36 +0000
+++ src/wui/interactive_player.cc	2013-07-30 22:51:28 +0000
@@ -46,7 +46,6 @@
 #include "ui_basic/unique_window.h"
 #include "upcast.h"
 #include "wui/building_statistics_menu.h"
-#include "wui/chatoverlay.h"
 #include "wui/encyclopedia_window.h"
 #include "wui/fieldaction.h"
 #include "wui/game_chat_menu.h"
@@ -153,10 +152,6 @@
 	m_toolbar.add(&m_toggle_statistics_menu, UI::Box::AlignLeft);
 	m_toolbar.add(&m_toggle_minimap,         UI::Box::AlignLeft);
 	m_toolbar.add(&m_toggle_buildhelp,       UI::Box::AlignLeft);
-	// Limit chat width to half the screen, to limit the damage lamers can do
-	// by flooding chat messages
-	m_chatOverlay =
-		new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25);
 	if (multiplayer) {
 		m_toolbar.add(&m_toggle_chat,            UI::Box::AlignLeft);
 		m_toggle_chat.set_visible(false);

=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc	2013-07-26 20:19:36 +0000
+++ src/wui/interactive_spectator.cc	2013-07-30 22:51:28 +0000
@@ -28,7 +28,6 @@
 #include "ui_basic/textarea.h"
 #include "ui_basic/unique_window.h"
 #include "upcast.h"
-#include "wui/chatoverlay.h"
 #include "wui/fieldaction.h"
 #include "wui/game_chat_menu.h"
 #include "wui/game_main_menu_save_game.h"
@@ -81,8 +80,6 @@
 	// TODO : instead of making unneeded buttons invisible after generation,
 	// they should not at all be generated. -> implement more dynamic toolbar UI
 	if (multiplayer) {
-		m_chatOverlay =
-			new ChatOverlay(this, 10, 25, get_w() - 10, get_h() - 25);
 		m_exit.set_visible(false);
 		m_exit.set_enabled(false);
 		m_save.set_visible(false);


Follow ups