http://bugs.freeciv.org/Ticket/Display.html?id=40487 >
> [book - Thu Sep 18 21:31:39 2008]:
>
> Here is my port of the allies-only button warclient feature for
> S2_1 and later. It has some improvements over the warclient
> version, namely that for local games (i.e. games on a forked
> server) the feature is hidden, and much improved code comments.
Updated to recent S2_1 and trunk, and somewhat improved.
---
何ヶ月も厳しい訓練して、今足の指で箸を割ることができる。
client/gui-gtk-2.0/chatline.c | 59 +-
client/gui-gtk-2.0/gui_main.c | 82 -
client/gui-gtk-2.0/gui_main.h |2 +
client/gui-gtk-2.0/pages.c|1 +
4 files changed, 141 insertions(+), 3 deletions(-)
diff --git a/client/gui-gtk-2.0/chatline.c b/client/gui-gtk-2.0/chatline.c
index e802940..89855bc 100644
--- a/client/gui-gtk-2.0/chatline.c
+++ b/client/gui-gtk-2.0/chatline.c
@@ -27,6 +27,7 @@
#include "packets.h"
#include "support.h"
+#include "client_main.h"
#include "climisc.h"
#include "gui_main.h"
#include "gui_stuff.h"
@@ -37,6 +38,55 @@
struct genlist *history_list;
int history_pos;
+/**
+ Helper function to determine if a given client input line is intended as
+ a "plain" public message. Note that messages prefixed with : are a
+ special case (explicit public messages), and will return FALSE.
+**/
+static bool is_plain_public_message(const char *s)
+{
+ /* FIXME: These prefix definitions are duplicated in the server. */
+ const char ALLIES_CHAT_PREFIX = '.';
+ const char SERVER_COMMAND_PREFIX = '/';
+ const char MESSAGE_PREFIX = ':';
+
+ const char *p;
+
+ /* If it is a server command or an explicit ally
+ * message, then it is not a public message. */
+ if (s[0] == SERVER_COMMAND_PREFIX || s[0] == ALLIES_CHAT_PREFIX) {
+return FALSE;
+ }
+
+ /* It might be a private message of the form
+ * 'player name with spaces':the message
+ * or with ". So skip past the player name part. */
+ if (s[0] == '\'' || s[0] == '"') {
+p = strchr(s + 1, s[0]);
+ } else {
+p = s;
+ }
+
+ /* Now we just need to check that it is not a private
+ * message. If we encounter a space then the preceeding
+ * text could not have been a user/player name (the
+ * quote check above eliminated names with spaces) so
+ * it must be a public message. Otherwise if we encounter
+ * the message prefix : then the text parsed up until now
+ * was a player/user name and the line is intended as
+ * a private message (or explicit public message if the
+ * first character is :). */
+ while (p != NULL && *p != '\0') {
+if (my_isspace(*p)) {
+ return TRUE;
+} else if (*p == MESSAGE_PREFIX) {
+ return FALSE;
+}
+p++;
+ }
+ return TRUE;
+}
+
/**
...
@@ -48,7 +98,14 @@ void inputline_return(GtkEntry *w, gpointer data)
theinput = gtk_entry_get_text(w);
if (*theinput) {
-send_chat(theinput);
+if (client_state() == C_S_RUNNING && allied_chat_only
+&& is_plain_public_message(theinput)) {
+ char buf[MAX_LEN_MSG];
+ my_snprintf(buf, sizeof(buf), ". %s", theinput);
+ send_chat(buf);
+} else {
+ send_chat(theinput);
+}
if (genlist_size(history_list) >= MAX_CHATLINE_HISTORY) {
void *data;
diff --git a/client/gui-gtk-2.0/gui_main.c b/client/gui-gtk-2.0/gui_main.c
index 653f6fb..2413a7e 100644
--- a/client/gui-gtk-2.0/gui_main.c
+++ b/client/gui-gtk-2.0/gui_main.c
@@ -57,6 +57,7 @@
#include "clinet.h"
#include "colors.h"
#include "connectdlg.h"
+#include "connectdlg_common.h"
#include "control.h"
#include "cma_fe.h"
#include "dialogs.h"
@@ -102,6 +103,7 @@ bool split_bottom_notebook = FALSE;
bool new_messages_go_to_top = FALSE;
bool show_message_window_buttons = TRUE;
bool metaserver_tab_first = FALSE;
+bool allied_chat_only = FALSE;
GtkWidget *toplevel;
GdkWindow *root_window;
@@ -172,6 +174,7 @@ char font_city_names[512] = "Sans Bold 10";
char font_city_productions[512] = "Serif 10";
static void split_bottom_notebook_callback(struct client_option *op);
+static void allied_chat_only_callback(struct client_option *op);
client_option gui_options[] = {
/* This option is the same as the one in gui-gtk */
@@ -242,6 +245,19 @@ client_option gui_options[] = {
"be the first notebook tab in the network page. This "
"option requires a restart in order to take effect."),
COC_NETWORK),
+ GEN_BOOL_OPTION_CB(allied_chat_only,
+ N_("Plain chat messages are sent to allies only"),
+ N_("If this option is enabled, then plain messages "
+"typed into the chat entry while t