With cordite in the air, splintered steel, shell casings and powder burns, there’s only one explanation...
Discuss & improve the game engine.

Moderators: sparcdr, torhu, Tequila

Clearer display for votes

Postby Barto » Sat Aug 24, 2013 4:59 pm

I have made a PM for TheDoctor about this, and he suggested me to repost it publicly (and he's right if someone else wants to have a small look into the code).
I'm just retaking what I said to TheDoctor without rephrasing much.

So,

Few months ago, Biondo suggested me to find a way to make the voting message clearer instead of the classic "VOTE(time):command value yes:X no:Y".

It is - in my opinion - a great idea to do. So I finally grabbed the code and found that displaying this message was into cg_draw.c at line 3144.
From that, I directly see that the "command value" string corresponds to cgs.voteString. So the best way for me would be to evaluate this char array (declared in cg_local.h, line 1563) and modify/replace if I can make a simpler display in a simple switch statement.("g_gametype Deathmatch" could be thus changed with "gametype Deathmatch" and "vstr nextmap br_map" in "change map to br_map")

The problem is, I don't know how to manipulate strings and use some functions like contains("text"), equals("text") or split("pattern") that can mostly be found in Java and not in C. (I mostly want detect the given char sequence and replace it with a new given one or just doing nothing if I have no replacement)
I'd be okay if I was able to edit this type and add the functions I wanted, but it is a char array at the end and there is thus no possible function to create on my knowledge (It's not an Object).

Also, I can see that I'd break the file logic that only has some display function if I would have recoded those required function.

So, at the end, I'm wondering how I am supposed to try to make this happen without breaking anything (code logic, file logic, etc.).
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Re: Clearer display for votes

Postby TheDoctor » Sun Aug 25, 2013 6:53 pm

Barto wrote:... find a way to make the voting message clearer instead of the classic "VOTE(time):command value yes:X no:Y".

OK. First, you should exactly specify what you want to change, before you attempt to implement it. IMHO, most people do understand the concept of voting, but don't care enough to vote on most things, i.e. they abstain.


Barto wrote:... make a simpler display in a simple switch statement.("g_gametype Deathmatch" could be thus changed with "gametype Deathmatch" and "vstr nextmap br_map" in "change map to br_map")

Not sure, this is well-thought-out. I agree, the standard messages are a bit unclear. That's why I've modified voting strings on BB a bit, to make things clearer. For example, \callvote map dm_dry produces
VOTE(time):map dm_dry (Deathmatch)
I think it is best to exactly show the command line, which did produce or would have produced the current vote. You may add an explanatory sentence, if you want, but don't get rid of the command line. The real problem is, most people don't get how to vote by command line. On BB however, there are votes you can only call for, if you use the command line, e.g. \callvote weapons knives.


Barto wrote:... found that displaying this message was into cg_draw.c at line 3144. From that, I directly see that the "command value" string corresponds to cgs.voteString. So the best way for me would be to evaluate this char array (declared in cg_local.h, line 1563) and modify/replace if I can.

Not exactly. Yes, cg_draw.c is responsible for drawing the string (presentation). However, in cg_servercmds.c it is defined (by the game module of the server, see Cmd_CallVote_f in g_cmds.c). Therefore, just replacing text on the client-side might not be a good approach.


Barto wrote:I don't know how to manipulate strings and use some functions like contains("text"), equals("text") or split("pattern") that can mostly be found in Java and not in C.

Welcome to the special hell that C is 8D. Indeed, there exists no object-orientated solution. In C, strings are character arrays of finite length or pointers to such arrays. There is no easy find and replace. There are some string related functions in qcommon/q_shared.c such as Q_strncpyz (character copy) and Q_stricmpn (chracter-wise comparison). You'd have to use those. Search for these function in the source code to find examples for their application.


Barto wrote:Also, I can see that I'd break the file logic that only has some display function if I would have recoded those required function.

Well, as I already have said, the client should display exactly the message, the server did specify. I'd consider it a hack, if the client would apply a substitution. For instance, such a client-side solution would not work on BB, since the game module would deliver different voting strings you wouldn't cover.


Barto wrote:So, at the end, I'm wondering how I am supposed to try to make this happen without breaking anything (code logic, file logic, etc.).

If I had the time and the motivation to enhance the voting function of SG, I would probably introduce another command CS_VOTE_STRING_EXPL in the server as well as the client and modify the client-side such that a small explanation is shown above the voting string such as "Biondo wants to change the map to dm_dry. Press F1 to abort the current game and switch to dm_dry. Press F2 to keep the current map." The explanation would have to be generated in Cmd_CallVote_f. This function already contains the code to analyze the structure of a vote (what kind of vote? what argument has been passed?), so you don't need to parse anything, but just to assemble the explanation. One would have to ensure, if the game does not set CS_VOTE_STRING_EXPL, the client still displays the vote.

However, before you attempt to implement this, please take the time to create a screenshot and a mock-up based thereon, to see if things would work out as planned. An easier way would be to let the server print a message in the background about the vote, see BB for "Biondo called a vote: map dm_dry (Deathmatch)". However, such a message would disappear after a few seconds.
Image
User avatar
TheDoctor
Smokin' Amigo!
 
Posts: 818
Joined: Sun Jun 06, 2010 3:31 am



Re: Clearer display for votes

Postby Barto » Mon Aug 26, 2013 2:25 pm

Firstly a big thanks for all your tips and help!

TheDoctor wrote:Not sure, this is well-thought-out. I agree, the standard messages are a bit unclear. That's why I've modified voting strings on BB a bit, to make things clearer.

Oh, I missed this, that's already something better than my initial thought.

TheDoctor wrote:I think it is best to exactly show the command line, which did produce or would have produced the current vote. You may add an explanatory sentence, if you want, but don't get rid of the command line. The real problem is, most people don't get how to vote by command line.

We're not all some console lovers, and that's why I wanna change this to something more clear. We could still append the initial cgs.voteString in brackets after the vote message for sure (but I think it starts to make a simple vote a little heavy).

TheDoctor wrote:Not exactly. Yes, cg_draw.c is responsible for drawing the string (presentation). However, in cg_servercmds.c it is defined (by the game module of the server, see Cmd_CallVote_f in g_cmds.c).

Oh, thanks, helps a lot. It even will avoid me to do some ugly char arrays manipulations.

TheDoctor wrote:I would probably introduce another command CS_VOTE_STRING_EXPL in the server as well as the client and modify the client-side such that a small explanation is shown above the voting string such as "Biondo wants to change the map to dm_dry.

I would have thought something which is simply to change the actual vote with just a simpler phrase.
VOTE(time): Biondo wants to change map to dm_dry. yes:X no:Y

Then I can simply replace the classic "Biondo called a vote" by "Biondo called a vote: cgs.voteString" to show the ´real´ command.

Anyway, I tried and failed (I'm not even surprised about it) even if I haven't edited that much code. I mostly added a voteStringExplanation char array that mostly is the same as the classic voteString. Surprisingly, I even messed more code than I would have expected. So here is my git diff...

I'll think that I'll give up, seing that I really don't have the ability to edit properly that kind of code without annoying a whole crowd... Maybe I will be enough skilled in a few years, but will SG be here?
Code: Select all
diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c
index d379c48..bfe5956 100644
--- a/code/cgame/cg_draw.c
+++ b/code/cgame/cg_draw.c
@@ -3141,12 +3141,12 @@ static void CG_DrawVote(void) {
       sec = 0;
    }
 #ifdef SMOKINGUNS
-   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo);
+   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteStringExplanation, cgs.voteYes, cgs.voteNo);
    CG_DrawSmallString( 0, 58, s, 1.0F );
    s = "or press ESC then click Vote";
    CG_DrawSmallString( 0, 58 + SMALLCHAR_HEIGHT + 2, s, 1.0F );
 #else
-   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo );
+   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteStringExplanation, cgs.voteYes, cgs.voteNo );
    CG_DrawSmallString( 0, 58, s, 1.0F );
 #endif
 }
diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h
index 94260e2..955fd6b 100644
--- a/code/cgame/cg_local.h
+++ b/code/cgame/cg_local.h
@@ -1561,6 +1561,7 @@ typedef struct {
    int            voteNo;
    qboolean      voteModified;         // beep whenever changed
    char         voteString[MAX_STRING_TOKENS];
+   char         voteStringExplanation[MAX_STRING_TOKENS];
 
    int            teamVoteTime[2];
    int            teamVoteYes[2];
diff --git a/code/cgame/cg_servercmds.c b/code/cgame/cg_servercmds.c
index 7768e38..9e3c551 100644
--- a/code/cgame/cg_servercmds.c
+++ b/code/cgame/cg_servercmds.c
@@ -378,6 +378,8 @@ static void CG_ConfigStringModified( void ) {
    } else if ( num == CS_VOTE_NO ) {
       cgs.voteNo = atoi( str );
       cgs.voteModified = qtrue;
+   } else if ( num == CS_VOTE_STRING_EXPL) {  //forum comment: i'm sure i'm missing smth here
+      Q_strncpyz( cgs.voteStringExplanation, str, sizeof( cgs.voteStringExplanation ) );
    } else if ( num == CS_VOTE_STRING ) {
       Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
 #ifndef SMOKINGUNS
diff --git a/code/game/bg_public.h b/code/game/bg_public.h
index 8d5a874..a6c7c4d 100644
--- a/code/game/bg_public.h
+++ b/code/game/bg_public.h
@@ -182,6 +182,7 @@ by Spoon
 
 #ifdef SMOKINGUNS
 #define   CS_MAPCYCLES         29      // for the map cycle vote menu
+#define CS_VOTE_STRING_EXPL      30      // clearer explanation of the votes
 #endif
 
 #define   CS_MODELS            32
diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c
index cba93d2..1b7815e 100644
--- a/code/game/g_cmds.c
+++ b/code/game/g_cmds.c
@@ -1947,6 +1947,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to play ", ent->client->pers.netname, gameNames[i] );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] );
    } else if ( !Q_stricmp( arg1, "map" ) ) {
       // special case for map changes, we want to reset the nextmap setting
@@ -1965,6 +1966,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       // We removed this code, this is not usefull anymore since I have modified server/sv_init.c to never
       // turn 'nextmap' to 'map_restart 0'
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteString ), "%s wants to change map to %s", ent->client->pers.netname, arg2 );
 #endif
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
 #ifdef SMOKINGUNS
@@ -1994,6 +1996,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr %s", token );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to change the mapcycle to %s", ent->client->pers.netname, token );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "mapcycle %s", token);
 
    } else if ( !Q_stricmp( arg1, "kick" ) ) {
@@ -2008,10 +2011,12 @@ void Cmd_CallVote_f( gentity_t *ent ) {
          return;
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %i \"Kicked by vote.\"", clientnum );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to kick %s", ent->client->pers.netname, arg_str );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kick \"%s\"", arg_str );
    } else if ( !Q_stricmp( arg1, "kicknum" ) ) {
       arg_str = ConcatArgs(3) ;
       Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %s %s", arg2, arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to kicknum %s", ent->client->pers.netname, arg_str );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kicknum %s %s", arg2 , arg_str );
    } else if ( !Q_stricmp( arg1, "mute" ) ) {
       arg_str = ConcatArgs(2) ;
@@ -2021,6 +2026,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
          return;
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "mute %i", clientnum );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to mute %s", ent->client->pers.netname, arg_str );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "mute \"%s\"", arg_str );
    } else if ( !Q_stricmp( arg1, "unmute" ) ) {
       arg_str = ConcatArgs(2) ;
@@ -2030,6 +2036,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
          return;
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "unmute %i", clientnum );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to unmute %s", ent->client->pers.netname, arg_str );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "unmute \"%s\"", arg_str );
    } else if ( !Q_stricmp( arg1, "timelimit" ) ) {
       i = atoi( arg2 );
@@ -2044,6 +2051,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to set %s as %d", arg1, i);
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s minutes", level.voteString );
 #endif
    } else if ( !Q_stricmp( arg1, "nextmap" ) ) {
@@ -2055,13 +2063,15 @@ void Cmd_CallVote_f( gentity_t *ent ) {
          return;
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap");
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to change the map to %s", ent->client->pers.netname, arg2 );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
    } else {
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s wants to set %s as %s", ent->client->pers.netname, arg1, arg2 );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
    }
 
-   trap_SendServerCommand( -1, va("print \"%s called a vote.\n\"", ent->client->pers.netname ) );
+   trap_SendServerCommand( -1, va("print \"%s called a vote: %s\n\"", ent->client->pers.netname, level.voteString ) );
 
 #ifdef SMOKINGUNS
    // Tequila: Log the callvote string
diff --git a/code/game/g_local.h b/code/game/g_local.h
index 88d2706..d93da4f 100644
--- a/code/game/g_local.h
+++ b/code/game/g_local.h
@@ -605,6 +605,7 @@ typedef struct {
 
    // voting state
    char      voteString[MAX_STRING_CHARS];
+   char      voteStringExplanation[MAX_STRING_CHARS];
    char      voteDisplayString[MAX_STRING_CHARS];
    int         voteTime;            // level.time vote was called
    int         voteExecuteTime;      // time the vote is executed
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Re: Clearer display for votes

Postby Biondo » Mon Aug 26, 2013 3:15 pm

Barto wrote:I'll think that I'll give up, seeing that I really don't have the ability to edit properly that kind of code without annoying a whole crowd... Maybe I will be enough skilled in a few years, but will SG be here?


You will be highly skilled in the twinkling of an eye if you don't give up (also at the risk of annoying the smart guys) ;-)
User avatar
Biondo
SG Website Designer
 
Posts: 543
Joined: Thu Oct 15, 2009 4:35 pm



Re: Clearer display for votes

Postby TheDoctor » Tue Aug 27, 2013 12:31 am

Barto wrote:Anyway, I tried and failed (I'm not even surprised about it) even if I haven't edited that much code.
Could you specify what kind of failure you were experiencing? Didn't the code compile? Dig the game crash thereafter? Did nothing change?
Image
User avatar
TheDoctor
Smokin' Amigo!
 
Posts: 818
Joined: Sun Jun 06, 2010 3:31 am



Re: Clearer display for votes

Postby /dev/random » Tue Aug 27, 2013 8:17 pm

If you're using another configstring for the vote description, you'll also have to set it. Otherwise the engine will never send it to the clients.
Code: Select all
trap_SetConfigstring( CS_VOTE_STRING_EXPL, level.voteStringExplanation );


You'll need to add this at the end of Cmd_CallVote_f(), where the other vote configstrings are set as well.

By the way, I'd recommend Doc's suggestion not to change the client unless necessary. I don't know the SG code by heart, but it might be sufficient to set voteDisplayString to a more descriptive value, maybe including color codes and such.

As a side note, remember to "reset" color codes wherever you include user input such as player names (i.e. printf("^7blabla %s^7 more bla", playername)).
User avatar
/dev/random
Smokin' Amigo!
 
Posts: 410
Joined: Thu Jan 22, 2009 1:58 pm



Re: Clearer display for votes

Postby Barto » Wed Aug 28, 2013 3:19 pm

TheDoctor wrote:Could you specify what kind of failure you were experiencing? Didn't the code compile? Dig the game crash thereafter? Did nothing change?

It seems I messed up the qvm I really don't know how. I was getting some missing textures as a crossair, a mouse freeze in the buy menu. It was really odd and at the end I can only explain this with a master failure of the qvm. (I still have some darker than usual brightness, no idea why)

/dev/random wrote:If you're using another configstring for the vote description, you'll also have to set it. Otherwise the engine will never send it to the clients.

This was my missing line! Thanks a lot!

I have tried to follow doc's steps and was able to get something decent for me (will it be for you?). Thanks again to point out that I forgot to set few "^7" after any probably player names.

I also tried to use voteDisplayString but the vote just hung at time zero, doing nothing at the end.

The only thing that is still bothering me, I wasn't to be able to kick myself while having colors into my name. Displaying that my colored name was not found...

git diff:
Code: Select all
diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c
index d379c48..fc6cde1 100644
--- a/code/cgame/cg_draw.c
+++ b/code/cgame/cg_draw.c
@@ -3141,7 +3141,7 @@ static void CG_DrawVote(void) {
       sec = 0;
    }
 #ifdef SMOKINGUNS
-   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo);
+   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteStringExplanation, cgs.voteYes, cgs.voteNo);
    CG_DrawSmallString( 0, 58, s, 1.0F );
    s = "or press ESC then click Vote";
    CG_DrawSmallString( 0, 58 + SMALLCHAR_HEIGHT + 2, s, 1.0F );
diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h
index 94260e2..955fd6b 100644
--- a/code/cgame/cg_local.h
+++ b/code/cgame/cg_local.h
@@ -1561,6 +1561,7 @@ typedef struct {
    int            voteNo;
    qboolean      voteModified;         // beep whenever changed
    char         voteString[MAX_STRING_TOKENS];
+   char         voteStringExplanation[MAX_STRING_TOKENS];
 
    int            teamVoteTime[2];
    int            teamVoteYes[2];
diff --git a/code/cgame/cg_servercmds.c b/code/cgame/cg_servercmds.c
index 7768e38..6793a7e 100644
--- a/code/cgame/cg_servercmds.c
+++ b/code/cgame/cg_servercmds.c
@@ -378,6 +378,8 @@ static void CG_ConfigStringModified( void ) {
    } else if ( num == CS_VOTE_NO ) {
       cgs.voteNo = atoi( str );
       cgs.voteModified = qtrue;
+   } else if (num == CS_VOTE_STRING_EXPL) {
+      Q_strncpyz( cgs.voteStringExplanation, str, sizeof( cgs.voteStringExplanation ) );
    } else if ( num == CS_VOTE_STRING ) {
       Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
 #ifndef SMOKINGUNS
diff --git a/code/game/bg_public.h b/code/game/bg_public.h
index 8d5a874..577a58c 100644
--- a/code/game/bg_public.h
+++ b/code/game/bg_public.h
@@ -182,6 +182,7 @@ by Spoon
 
 #ifdef SMOKINGUNS
 #define   CS_MAPCYCLES         29      // for the map cycle vote menu
+#define   CS_VOTE_STRING_EXPL      30
 #endif
 
 #define   CS_MODELS            32
diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c
index cba93d2..9ea2ce7 100644
--- a/code/game/g_cmds.c
+++ b/code/game/g_cmds.c
@@ -1948,6 +1948,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to play %s", ent->client->pers.netname, gameNames[i] );
    } else if ( !Q_stricmp( arg1, "map" ) ) {
       // special case for map changes, we want to reset the nextmap setting
       // this allows a player to change maps, but not upset the map rotation
@@ -1965,6 +1966,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       // We removed this code, this is not usefull anymore since I have modified server/sv_init.c to never
       // turn 'nextmap' to 'map_restart 0'
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to change map to %s", ent->client->pers.netname, arg2 );
 #endif
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
 #ifdef SMOKINGUNS
@@ -1995,6 +1997,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr %s", token );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "mapcycle %s", token);
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to change the mapcycle to %s", ent->client->pers.netname, token );
 
    } else if ( !Q_stricmp( arg1, "kick" ) ) {
       // Tequila: Replace kick command by safer sendaway one and merging other arguments
@@ -2009,10 +2012,12 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %i \"Kicked by vote.\"", clientnum );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kick \"%s\"", arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to kick %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "kicknum" ) ) {
       arg_str = ConcatArgs(3) ;
       Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %s %s", arg2, arg_str );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kicknum %s %s", arg2 , arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to kicknum %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "mute" ) ) {
       arg_str = ConcatArgs(2) ;
       clientnum = ClientNumberFromCleanName( arg_str );
@@ -2022,6 +2027,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "mute %i", clientnum );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "mute \"%s\"", arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to mute %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "unmute" ) ) {
       arg_str = ConcatArgs(2) ;
       clientnum = ClientNumberFromCleanName( arg_str );
@@ -2031,6 +2037,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "unmute %i", clientnum );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "unmute \"%s\"", arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to unmute %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "timelimit" ) ) {
       i = atoi( arg2 );
 // Tequila: Clamp timelimit within acceptable values like 30 days
@@ -2045,6 +2052,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s minutes", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to set time limit as %d minutes", i);
 #endif
    } else if ( !Q_stricmp( arg1, "nextmap" ) ) {
       char   s[MAX_STRING_CHARS];
@@ -2056,12 +2064,18 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap");
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants switch to next map %s", ent->client->pers.netname, s );
+   } else if ( !Q_stricmp(arg1, "map_restart") ) {
+      Com_sprintf( level.voteString, sizeof( level.voteString ), "%s", arg1);
+      Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants restart map", ent->client->pers.netname );
    } else {
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to set %s as %s", ent->client->pers.netname, arg1, arg2 );
    }
 
-   trap_SendServerCommand( -1, va("print \"%s called a vote.\n\"", ent->client->pers.netname ) );
+   trap_SendServerCommand( -1, va("print \"%s^7 called a vote: %s\n\"", ent->client->pers.netname, level.voteString ) );
 
 #ifdef SMOKINGUNS
    // Tequila: Log the callvote string
@@ -2084,6 +2098,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
    trap_SetConfigstring( CS_VOTE_TIME, va("%i", level.voteTime ) );
    trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString );
+   trap_SetConfigstring( CS_VOTE_STRING_EXPL, level.voteStringExplanation );
    trap_SetConfigstring( CS_VOTE_YES, va("%i", level.voteYes ) );
    trap_SetConfigstring( CS_VOTE_NO, va("%i", level.voteNo ) );
 }
diff --git a/code/game/g_local.h b/code/game/g_local.h
index 88d2706..a963cfa 100644
--- a/code/game/g_local.h
+++ b/code/game/g_local.h
@@ -606,6 +606,7 @@ typedef struct {
    // voting state
    char      voteString[MAX_STRING_CHARS];
    char      voteDisplayString[MAX_STRING_CHARS];
+   char      voteStringExplanation[MAX_STRING_CHARS];
    int         voteTime;            // level.time vote was called
    int         voteExecuteTime;      // time the vote is executed
    int         voteYes;
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Re: Clearer display for votes

Postby TheDoctor » Thu Aug 29, 2013 1:52 pm

Barto wrote:I have tried to follow doc's steps and was able to get something decent for me (will it be for you?)

Please provide a screenshot.
Image
User avatar
TheDoctor
Smokin' Amigo!
 
Posts: 818
Joined: Sun Jun 06, 2010 3:31 am



Re: Clearer display for votes

Postby Barto » Thu Aug 29, 2013 3:35 pm

Please provide a screenshot.

Oh, sorry, my bad! It just seems I will have to review the kicknum command, but the rest looks fine. I started with a clean reset of the config for the screenshots.

I have included (it is surely useless for us), where I fail to callvote for kicking my colored name.

g_gametype Deathmatch:
Image

kick Oakley:
Image

map dm_fort:
Image

map_restart: (oh, missing "to"), fixed
Image

vstr nextmap: (I also show which map it is)
Image

kick |RP|ElBarto via the UI: (fails anyhow the client id)
Image

fraglimit 10 via the console: (else case)
Image

kicknum 0: fails here, I'll have to investigate more about arg_str. (I'd like to display the client name)
Image

I still - imho thinks that the game was too dark for me, maybe just some misconfiguration of r_ignorehwgamma. It's only occurring on my laptop and not on my desktop.
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Re: Clearer display for votes

Postby /dev/random » Sat Aug 31, 2013 12:06 pm

Barto wrote:vstr nextmap: (I also show which map it is)

Does this work with map rotations scripts which are more complex than just;
Code: Select all
set nextmap "map dm_dry"

e.g.
Code: Select all
set nextmap    "vstr nextscript"
set nextscript "vstr next_gametype; set nextmap vstr nextscript"
// etc.


Barto wrote:kick |RP|ElBarto via the UI: (fails anyhow the client id)

I haven't verified this, but it looks like the invocation of ClientNumberFromCleanName() within the "kick" clause should do so with a Q_CleanStr() copy of arg_str (assuming the client ui sends the player name verbatim).

Barto wrote:kicknum 0: fails here, I'll have to investigate more about arg_str. (I'd like to display the client name)

You'll want to do something along the lines of
Code: Select all
} else if ( !Q_stricmp( arg1, "kicknum" ) ) {
   clientnum = atoi(arg2);

   // TODO: assert that 0 <= clientnum < level.maxclients
   // additionally check whether that client is connected, not a localClient (i.e. the game host) etc. though this is done by kicknum as well

   // Concat arguments 3 to rest into arg_str
   // i.e. with "callvote kicknum 42 you   suck" you'd get arg_str "you suck"
   // with "callvote kicknum 42" you'd get arg_str "" (empty, so arg_str[0] == 0 or strlen(arg_str) == 0)
   arg_str = ConcatArgs(3) ;
   Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %i %s", clientnum, arg_str );
   Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kicknum %i %s", clientnum , arg_str );
   Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to kick %s^7", ent->client->pers.netname, level.clients[clientnum].pers.netname );
   // You might want to put arg_str into voteStringExplanation as well, since it is the optional kick "reason", see "Kicked by vote" for the regular "kick" vote.
   // The client will see this as "was kicked: blabla" (e.g. "was kicked: Kicked by vote", or just "was kicked" if no reason is supplied, see Svcmd_KickNum_f()
} else if ( !Q_stricmp( arg1, "mute" ) ) {
User avatar
/dev/random
Smokin' Amigo!
 
Posts: 410
Joined: Thu Jan 22, 2009 1:58 pm



Re: Clearer display for votes

Postby Barto » Wed Sep 04, 2013 4:52 pm

/dev/random wrote:Does this work with map rotations scripts which are more complex

In your case, it will only display (I haven't tested though):
Code: Select all
PLAYER wants to switch to next map nextscript

If it not what you want, I can just cancel the changes I made for the nextmap command or I can simply remove the "next map" part of the message.

/dev/random wrote:I haven't verified this, but it looks like the invocation of ClientNumberFromCleanName() within the "kick" clause should do so with a Q_CleanStr() copy of arg_str (assuming the client ui sends the player name verbatim).

Works fine, apart that I don't know how to do a full array copy (my current method doensn't display colors)

And I fixed kicknum as you said too, I admit that I had the feeling that this function was missing something...

Git diff as a spoiler:
Code: Select all
diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c
index d379c48..fc6cde1 100644
--- a/code/cgame/cg_draw.c
+++ b/code/cgame/cg_draw.c
@@ -3141,7 +3141,7 @@ static void CG_DrawVote(void) {
       sec = 0;
    }
 #ifdef SMOKINGUNS
-   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo);
+   s = va("VOTE(%i):%s yes:%i no:%i", sec, cgs.voteStringExplanation, cgs.voteYes, cgs.voteNo);
    CG_DrawSmallString( 0, 58, s, 1.0F );
    s = "or press ESC then click Vote";
    CG_DrawSmallString( 0, 58 + SMALLCHAR_HEIGHT + 2, s, 1.0F );
diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h
index 94260e2..955fd6b 100644
--- a/code/cgame/cg_local.h
+++ b/code/cgame/cg_local.h
@@ -1561,6 +1561,7 @@ typedef struct {
    int            voteNo;
    qboolean      voteModified;         // beep whenever changed
    char         voteString[MAX_STRING_TOKENS];
+   char         voteStringExplanation[MAX_STRING_TOKENS];
 
    int            teamVoteTime[2];
    int            teamVoteYes[2];
diff --git a/code/cgame/cg_servercmds.c b/code/cgame/cg_servercmds.c
index 7768e38..6793a7e 100644
--- a/code/cgame/cg_servercmds.c
+++ b/code/cgame/cg_servercmds.c
@@ -378,6 +378,8 @@ static void CG_ConfigStringModified( void ) {
    } else if ( num == CS_VOTE_NO ) {
       cgs.voteNo = atoi( str );
       cgs.voteModified = qtrue;
+   } else if (num == CS_VOTE_STRING_EXPL) {
+      Q_strncpyz( cgs.voteStringExplanation, str, sizeof( cgs.voteStringExplanation ) );
    } else if ( num == CS_VOTE_STRING ) {
       Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
 #ifndef SMOKINGUNS
diff --git a/code/game/bg_public.h b/code/game/bg_public.h
index 8d5a874..577a58c 100644
--- a/code/game/bg_public.h
+++ b/code/game/bg_public.h
@@ -182,6 +182,7 @@ by Spoon
 
 #ifdef SMOKINGUNS
 #define   CS_MAPCYCLES         29      // for the map cycle vote menu
+#define   CS_VOTE_STRING_EXPL      30
 #endif
 
 #define   CS_MODELS            32
diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c
index cba93d2..9907941 100644
--- a/code/game/g_cmds.c
+++ b/code/game/g_cmds.c
@@ -1948,6 +1948,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to play %s", ent->client->pers.netname, gameNames[i] );
    } else if ( !Q_stricmp( arg1, "map" ) ) {
       // special case for map changes, we want to reset the nextmap setting
       // this allows a player to change maps, but not upset the map rotation
@@ -1965,6 +1966,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       // We removed this code, this is not usefull anymore since I have modified server/sv_init.c to never
       // turn 'nextmap' to 'map_restart 0'
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to change map to %s", ent->client->pers.netname, arg2 );
 #endif
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
 #ifdef SMOKINGUNS
@@ -1995,13 +1997,14 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr %s", token );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "mapcycle %s", token);
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to change the mapcycle to %s", ent->client->pers.netname, token );
 
    } else if ( !Q_stricmp( arg1, "kick" ) ) {
       // Tequila: Replace kick command by safer sendaway one and merging other arguments
       //Com_sprintf( level.voteString, sizeof( level.voteString ), "sendaway \"%s\"", ConcatArgs(2) );
       
       // Joe Kari: use of more standard kicknum command instead
-      arg_str = ConcatArgs(2) ;
+      arg_str = Q_CleanStr( ConcatArgs(2) );
       clientnum = ClientNumberFromCleanName( arg_str );
       if ( clientnum < 0 ) {
          trap_SendServerCommand( ent-g_entities, va("print \"%s not found.\n\"", arg_str ) );
@@ -2009,10 +2012,21 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %i \"Kicked by vote.\"", clientnum );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kick \"%s\"", arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to kick %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "kicknum" ) ) {
-      arg_str = ConcatArgs(3) ;
+      arg_str = ConcatArgs(3);
+      clientnum = atoi(arg2);
+      if (clientnum < 0 || clientnum >= level.maxclients) {
+         trap_SendServerCommand( ent-g_entities, va("print \"Invalid client number: %s\"\n", arg2) );
+         return;
+      }
+      if (level.clients[clientnum].pers.connected == CON_DISCONNECTED) {
+         trap_SendServerCommand( ent-g_entities, va("print \"Invalid client number: %s\"\n", arg2) );
+         return;
+      }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "kicknum %s %s", arg2, arg_str );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "kicknum %s %s", arg2 , arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to kicknum %s^7 (reason: \"%s^7\")", ent->client->pers.netname, level.clients[clientnum].pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "mute" ) ) {
       arg_str = ConcatArgs(2) ;
       clientnum = ClientNumberFromCleanName( arg_str );
@@ -2022,6 +2036,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "mute %i", clientnum );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "mute \"%s\"", arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to mute %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "unmute" ) ) {
       arg_str = ConcatArgs(2) ;
       clientnum = ClientNumberFromCleanName( arg_str );
@@ -2031,6 +2046,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "unmute %i", clientnum );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteString ), "unmute \"%s\"", arg_str );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to unmute %s^7", ent->client->pers.netname, arg_str );
    } else if ( !Q_stricmp( arg1, "timelimit" ) ) {
       i = atoi( arg2 );
 // Tequila: Clamp timelimit within acceptable values like 30 days
@@ -2045,6 +2061,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s minutes", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to set time limit as %d minutes", i);
 #endif
    } else if ( !Q_stricmp( arg1, "nextmap" ) ) {
       char   s[MAX_STRING_CHARS];
@@ -2056,12 +2073,18 @@ void Cmd_CallVote_f( gentity_t *ent ) {
       }
       Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap");
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to switch to %s", ent->client->pers.netname, s );
+   } else if ( !Q_stricmp(arg1, "map_restart") ) {
+      Com_sprintf( level.voteString, sizeof( level.voteString ), "%s", arg1);
+      Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to restart map", ent->client->pers.netname );
    } else {
       Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 );
       Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
+      Com_sprintf( level.voteStringExplanation, sizeof( level.voteStringExplanation ), "%s^7 wants to set %s as %s", ent->client->pers.netname, arg1, arg2 );
    }
 
-   trap_SendServerCommand( -1, va("print \"%s called a vote.\n\"", ent->client->pers.netname ) );
+   trap_SendServerCommand( -1, va("print \"%s^7 called a vote: %s\n\"", ent->client->pers.netname, level.voteString ) );
 
 #ifdef SMOKINGUNS
    // Tequila: Log the callvote string
@@ -2084,6 +2107,7 @@ void Cmd_CallVote_f( gentity_t *ent ) {
 
    trap_SetConfigstring( CS_VOTE_TIME, va("%i", level.voteTime ) );
    trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString );
+   trap_SetConfigstring( CS_VOTE_STRING_EXPL, level.voteStringExplanation );
    trap_SetConfigstring( CS_VOTE_YES, va("%i", level.voteYes ) );
    trap_SetConfigstring( CS_VOTE_NO, va("%i", level.voteNo ) );
 }
diff --git a/code/game/g_local.h b/code/game/g_local.h
index 88d2706..a963cfa 100644
--- a/code/game/g_local.h
+++ b/code/game/g_local.h
@@ -606,6 +606,7 @@ typedef struct {
    // voting state
    char      voteString[MAX_STRING_CHARS];
    char      voteDisplayString[MAX_STRING_CHARS];
+   char      voteStringExplanation[MAX_STRING_CHARS];
    int         voteTime;            // level.time vote was called
    int         voteExecuteTime;      // time the vote is executed
    int         voteYes;


One problem remaining, apart that I don't know how to correctly code in C (which is quite problematic here), I am unable to get running the 64bits build of the game ... Any idea how I messed up this?
Error log:
(...)
File "vm/ui.qvm" found in "./smokinguns/zzz_votes.pk3"
...which has vmMagic VM_MAGIC_VER2
Loading 1124 jump table targets
total 0, hsize 1021, zero 1021, min 0, max 0
total 4423, hsize 1021, zero 35, min 0, max 15
VM file ui compiled to 1398118 bytes of code (0x7f65d86f6000 - 0x7f65d884b566)
compilation took 0.324554 seconds
ui loaded in 2455840 bytes on the hunk
********************
ERROR: opStack corrupted in compiled code (offset 4)
********************
Segmentation error (core dumped) //translated from french
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Re: Clearer display for votes

Postby /dev/random » Wed Sep 04, 2013 9:07 pm

Barto wrote:In your case, it will only display (I haven't tested though):
Code: Select all
PLAYER wants to switch to next map nextscript

If it not what you want, I can just cancel the changes I made for the nextmap command or I can simply remove the "next map" part of the message.

I have no preference for either solution, I just wanted to point out that it might not work as intended.

Barto wrote:Works fine, apart that I don't know how to do a full array copy (my current method doensn't display colors)

You'll most likely want to use a temporary buffer, copy the original string into it, then call Q_CleanStr() on it.
Code: Select all
char cleanName[MAX_STRING_CHARS]; // this is most likely to large
arg_str = ConcatArgs(2);
Q_strncpyz(cleanName, arg2, sizeof(cleanName));
clientnum = ClientNumberFromCleanName( cleanName );
// you can either print arg_str or cleanName to the players

It seems like ForceUniqueName() sets a level.clients[clientNum].pers.cleanname attribute (not present in Q3), so you might be able to use that one as well instead of creating the cleanName copy.

Barto wrote:I am unable to get running the 64bits build of the game ... Any idea how I messed up this?

That error should not happen and neither should the engine segfault. I've seen cases where this was caused by corrupted QVMs, you might try a make clean (or even rm -rf build/).

P.S.: That inline diff is a little difficult to read, any change you could put the whole thing on GitHub or similar, so one can easily browse the code/changes?
User avatar
/dev/random
Smokin' Amigo!
 
Posts: 410
Joined: Thu Jan 22, 2009 1:58 pm



Re: Clearer display for votes

Postby Barto » Thu Sep 05, 2013 4:07 pm

/dev/random wrote:I have no preference for either solution, I just wanted to point out that it might not work as intended.

Understood. At the end I would really appreciate to see some more infos but I also cannot recursively go into the script to get the next map too. Also "PLAYER wants to switch to vstr nextscript" is the right output. At the end, I will give the code to Tequila and he will have the last words.

/dev/random wrote:You'll most likely want to use a temporary buffer, copy the original string into it, then call Q_CleanStr() on it.

That's the way I tried and it fully works, thanks!

/dev/random wrote:It seems like ForceUniqueName() sets a level.clients[clientNum].pers.cleanname attribute (not present in Q3), so you might be able to use that one as well instead of creating the cleanName copy.

I prefer the previous way for those reasons:
  • level.clients[clientnum].pers.cleanname already requires a cleanname to get the client number, so I would need to Q_CleanStr arg_str
  • other commands uses a non-clean arg_str to work, making the exception is no good for me.

/dev/random wrote:That error should not happen and neither should the engine segfault. I've seen cases where this was caused by corrupted QVMs, you might try a make clean (or even rm -rf build/).

No way :( (rm -rf build/ did not work). I start to think I either messed up something in the qvm (I don't know how the game exactly handle it). Maybe it comes from eclipse (4.3) or gcc-multilib (4.8.1) on my archlinux... Odd it's also only the 64bits build...

/dev/random wrote:P.S.: That inline diff is a little difficult to read, any change you could put the whole thing on GitHub or similar, so one can easily browse the code/changes?

Yeah, I initially planned to make it in one commit (as you see, I'm trying and failing a lot and I want to put everything in one clean commit and not fork the game 10 times too). Is pastebin something more proper for you? If yes, here it is (valid one month). I'm ready to commit if there are no big fixes to do before. I want to give the minimum of commits to Tequila without any git revert in the mess, I hope you understand because I think I'm quite unclear.
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Re: Clearer display for votes

Postby /dev/random » Thu Sep 05, 2013 9:36 pm

Barto wrote:No way :( (rm -rf build/ did not work). I start to think I either messed up something in the qvm (I don't know how the game exactly handle it). Maybe it comes from eclipse (4.3) or gcc-multilib (4.8.1) on my archlinux... Odd it's also only the 64bits build...

QVMs are not built with GCC (directly). Instead, your compiler is used to create q3asm, q3cpp, q3lcc and q3rcc which then compile the .c gamecode into .asm and finally .qvm. Those tools might have bugs themselves, but I rather doubt it.
When you say rm didn't work, do you mean rm failed or do you mean it removed the build/ folder correctly, but did not fix the segfault problem?

Barto wrote:Yeah, I initially planned to make it in one commit (as you see, I'm trying and failing a lot and I want to put everything in one clean commit and not fork the game 10 times too). Is pastebin something more proper for you? If yes, here it is (valid one month). I'm ready to commit if there are no big fixes to do before. I want to give the minimum of commits to Tequila without any git revert in the mess, I hope you understand because I think I'm quite unclear.

I haven't used it myself, but if all you want is a single commit, you might try using git rebase/stash.
Oh, and thanks for the pastebin link, it's much more pleasant to read :)
User avatar
/dev/random
Smokin' Amigo!
 
Posts: 410
Joined: Thu Jan 22, 2009 1:58 pm



Re: Clearer display for votes

Postby Barto » Fri Sep 06, 2013 12:36 pm

/dev/random wrote:When you say rm didn't work, do you mean rm failed or do you mean it removed the build/ folder correctly, but did not fix the segfault problem?

I entirely deleted the build folder with success, I compiled the game again (this time without any -jX options to be sure with a classic "make && linux32 make") and I still get the segfault. Have you ever had that kind of issue? Could it come from git (1.8.4), some weird #define (#define CS_VOTE_STRING_EXPL 30 I added)? Would it be a good idea if I just re-download the whole repo again (svn lovers know what I mean)?

I tried to run a make debug and it works fine (no segfault, but still darker screen compared to the master git branch).
"Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again)."
User avatar
Barto
Jeuxlinux Admin
 
Posts: 360
Joined: Fri Oct 23, 2009 5:08 pm
Location: Switzerland



Next

Return to Code

Show Sidebar
Show Sidebar

User Control Panel

cron