Connect to ip menu


(Xterm1n8or) #1

Hi ppl :smiley:

One of the things that has bugged me for ages is the connect to ip menu.
I don’t like the fact that you need to type in the address every time. I would like to be able to select it from a list ( if it has been previously entered ).
So, with this in mind, i have made the connecttoip menu window bigger ( on the y coord ), and in between the Server IP field and the Back, Connect buttons, I have put in another field : IP List, and another 2 buttons : Add, Remove.

The IP List field is supposed to show about 5 entries and be able to scroll, and i’ve included buttons to manually add and remove entries.
Unfortunately that’s as far as i can get. I’ve looked through loads of files trying to find something that looks remotely similar to what i need and i have of course searched the forums but i’m at a loss as to where to go from here.

Was wondering if anyone could help me out here or point me in the right direction.
Many thanks :slight_smile:

:idea: An after thought. I’ve been trying to look into how the game saves other settings into a .cfg file


(Nail) #2

can’t you just use “favorites” ?


(Elite) #3

Steps needed:

  • Create a structure to hold the data (probably like a name and ip)
  • Create an array of these structures for however many you need (easiest to define a MAX_SERVERS type thing and use that for your upper boundary)
  • Load records (open a file, read from the file, close the file)
  • Write records (open file, write data to file, close file)

trap_fs_openfile opens it, trap_fs_read reads it, trap_fs_write writes it, do a search on those, they will give you errors if you type them as shown becuase that’s improper capitals and w/e.

There are a hundred examples all around you. In the source, other systems are the etpub repository, the xpsave and shrubbot systems are identical to what you seem like you want, just don’t record xp, record the servers and place it in cg_ instead.

Like mentioned above, the best bet is to enumerate the list of favorites in the menu.


(Xterm1n8or) #4

Hello :smiley:

can’t you just use “favorites” ?

Funny you should ask that because it is something else that i am planning on looking into. The thing is, the favourites thing has never seemed to work for me. I check the checkbox and play, but when i next play ( IF the server appears in the browser ), the box is unchecked and changing the “source” button to favourires always brings up a blank.
I use the connect to ip option because it saves me having to scroll through the browser to find it, and as i said that’s if it even shows up. Sometimes it does, sometimes it doesn’t :?

  • Create a structure to hold the data (probably like a name and ip)
  • Create an array of these structures for however many you need (easiest to define a MAX_SERVERS type thing and use that for your upper boundary)
  • Load records (open a file, read from the file, close the file)
  • Write records (open file, write data to file, close file)

Thanks for the pointer :slight_smile: I do get what you’ve put but need to do more research. Any chance you could point me to some of these examples?

How do you ppl know where to put this stuff without spending hours of scrolling through files? Any help would be most appreciated.

Many thanks :slight_smile:


(Elite) #5

Create new files.

In the header, put your structures, defines, function prototypes, etc. In the source file, put your globals etc, and actual functions.

Then, when the menu is opened, you could read the file (or better yet, when cgame it loaded to avoid unessary overhead of always loading the file) and save the file when the menu is closed (or better yet, only write the new entry if there is a new entry when the menu is closed, or even better yet keep it in a variable array until cgame is shutdown to prevent uneccesary overhead).

EDIT IN PROGRESS:
Going to do a quick example, still typing it out

EDIT:
Actually, I’m not going to do an example. Just take a look at this xpsave system and it has everything you need; it can read/write files, etc. If you still can’t quite grasp it, I may help you out with an example of what you want, but it’s best to learn on your own. BTW, everyone here (due to lack of documentation I figure, unless I’m really missing something) has spent many hours going though the source to figure out what does what, etc. It’s not an easy task. ANyhow, here’s the files… (igone the numbers on the side, I copied and pasted from svn and those are just the line numbers they are on)

g_xpsave.h

    1 #ifndef G_XPSAVE_H
    2 #define G_XPSAVE_H
    3 
    4 //defines
    5 #define XPSAVE_FILENAME			"xpsave.dat"					//name of xpsave file
    6 #define XPSAVE_MAX_RECORDS		16384							//maximum xpsave records
    7 #define XPSAVE_ENABLED			1								//determines if xpsave is enabled
    8 
    9 //xpsave structure
   10 typedef struct {
   11 	char	guid[33];											//client guid
   12 	float	skill[SK_NUM_SKILLS];								//client skills
   13 	int		time;												//xpsave expiration
   14 } g_XPSave_t;
   15 
   16 //function prototypes
   17 void G_XPSave_ReadConfig();										//read xpsave records from file
   18 void G_XPSave_WriteConfig();									//write xpsave records to file
   19 qboolean G_XPSave_Load(gentity_t* ent);							//load client xpsave record
   20 qboolean G_XPSave_Store(gentity_t* ent);						//store client xpsave record
   21 void G_XPSave_Cleanup();										//cleanup xpsave data
   22 void G_XPSave_Duration(int secs, char *duration, int dursize);	//get duration of time
   23 void G_XPSave_ReadConfig_String(char **cnf, char *s, int size);	//read strings from config file
   24 void G_XPSave_ReadConfig_Int(char **cnf, int *v);				//read integers from config file
   25 void G_XPSave_ReadConfig_Float(char **cnf, float *v);			//read floats from config file
   26 void G_XPSave_WriteConfig_String(char *s, fileHandle_t f);		//write strings to config file
   27 void G_XPSave_WriteConfig_Int(int v, fileHandle_t f);			//write integers to config file
   28 void G_XPSave_WriteConfig_Float(float v, fileHandle_t f);		//write floats to config file
   29 
   30 #endif

g_xpsave.c

    1 //includes
    2 #include "g_local.h"
    3 
    4 //globals
    5 g_XPSave_t *g_XPSaves[XPSAVE_MAX_RECORDS];
    6 
    7 //read xpsave records from file
    8 void G_XPSave_ReadConfig() {
    9 	//declare variables
   10 	int				len, i;
   11 	fileHandle_t	f;
   12 	char			*cnf, *cnf2, *t;
   13 	qboolean		xpsave_open			= qfalse;
   14 	int				xc					= 0;
   15 	g_XPSave_t		*x					= g_XPSaves[0];
   16 	float			skill;
   17 
   18 	//make sure xpsave is enabled
   19 	if(!(g_xpsave.integer & XPSAVE_ENABLED)) {
   20 		return;
   21 	}
   22 
   23 	//open xpsave file
   24 	len = trap_FS_FOpenFile(XPSAVE_FILENAME, &f, FS_READ) ;
   25 	if(len < 0) {
   26 		G_Printf("XPSave: could not open xpsave file (%s)
", XPSAVE_FILENAME);
   27 		return;
   28 	}
   29 
   30 	//read file
   31 	cnf = malloc(len+1);
   32 	cnf2 = cnf;
   33 	trap_FS_Read(cnf, len, f);
   34 	*(cnf + len) = '\0';
   35 
   36 	//close file
   37 	trap_FS_FCloseFile(f);
   38 
   39 	//cleanup old xpsave data
   40 	G_XPSave_Cleanup();
   41 
   42 	//parse file
   43 	t = COM_Parse(&cnf);
   44 	while(*t) {
   45 		if(!Q_stricmp(t, "[xpsave]")) {
   46 			if(xpsave_open) {
   47 				g_XPSaves[xc++] = x;
   48 			}
   49 			xpsave_open = qfalse;
   50 		}
   51 
   52 		if(xpsave_open) {
   53 			if(!Q_stricmp(t, "guid")) {
   54 				G_XPSave_ReadConfig_String(&cnf, x->guid, sizeof(x->guid));
   55 			} else if(!Q_stricmpn(t, "skill[", 6)) {
   56 				for(i=0; i<SK_NUM_SKILLS; i++) {
   57 					if(Q_stricmp(t, va("skill[%i]", i))) {
   58 						continue;
   59 					}
   60 					G_XPSave_ReadConfig_Float(&cnf, &skill);
   61 					x->skill[i] = skill;
   62 					break;
   63 				}
   64 			} else if(!Q_stricmp(t, "time")) {
   65 				G_XPSave_ReadConfig_Int(&cnf, &x->time);
   66 			} else {
   67 				G_Printf("XPSave: readconfig error (parse error near %s on line %d)
", t, COM_GetCurrentParseLine());
   68 			}
   69 		}
   70 
   71 		if(!Q_stricmp(t, "[xpsave]")) {
   72 			if(xc >= XPSAVE_MAX_RECORDS) {
   73 				G_Printf("XPSave: XPSAVE_MAX_RECORDS exceeded (%i)", XPSAVE_MAX_RECORDS);
   74 				return;
   75 			}
   76 			x = malloc(sizeof(g_XPSave_t));
   77 			x->guid[0] = '\0';
   78 			for(i=0; i<SK_NUM_SKILLS; i++) {
   79 				x->skill[i] = 0.0f;
   80 			}
   81 			x->time = 0;
   82 			xpsave_open = qtrue;
   83 		}
   84 		t = COM_Parse(&cnf);
   85 	}
   86 
   87 	//make sure last xpsave record is used also
   88 	if(xpsave_open) {
   89 		g_XPSaves[xc++] = x;
   90 	}
   91 
   92 	//release resources
   93 	free(cnf2);
   94 
   95 	//display message
   96 	G_Printf("XPSave: loaded %d xpsave records
", xc);
   97 }
   98 
   99 //write xpsave records to file
  100 void G_XPSave_WriteConfig() {
  101 	//declare variables
  102 	time_t			t;
  103 	int				len, i, j, age;
  104 	fileHandle_t	f;
  105 
  106 	//make sure xpsave is enabled
  107 	if(!(g_xpsave.integer & XPSAVE_ENABLED)) {
  108 		return;
  109 	}
  110 
  111 	time(&t);
  112 
  113 	//open xpsave file
  114 	len = trap_FS_FOpenFile(XPSAVE_FILENAME, &f, FS_WRITE);
  115 	if(len < 0) {
  116 		G_Printf("XPSave: could not open xpsave file (%s)
", XPSAVE_FILENAME);
  117 	}
  118 
  119 	//write xpsave records to file
  120 	for(i=0; g_XPSaves[i]; i++) {
  121 		if(!g_XPSaves[i]->time) {
  122 			continue;
  123 		}
  124 		age = t - g_XPSaves[i]->time;
  125 		if((age > g_xpsave_duration.integer) && (g_xpsave_duration.integer > 0)) {
  126 			continue;
  127 		}
  128 		trap_FS_Write("[xpsave]
", 9, f);
  129 		trap_FS_Write("guid             = ", 19, f);
  130 		G_XPSave_WriteConfig_String(g_XPSaves[i]->guid, f);
  131 		for(j=0; j<SK_NUM_SKILLS; j++) {
  132 			if(g_XPSaves[i]->skill[j] == 0.0f) {
  133 				continue;
  134 			}
  135 			trap_FS_Write(va("skill[%i]         = ", j), 19, f);
  136 			G_XPSave_WriteConfig_Float(g_XPSaves[i]->skill[j], f);
  137 		}
  138 		trap_FS_Write("time             = ", 19, f);
  139 		G_XPSave_WriteConfig_Int(g_XPSaves[i]->time, f);
  140 		trap_FS_Write("
", 1, f);
  141 	}
  142 
  143 	//close file
  144 	trap_FS_FCloseFile(f);
  145 
  146 	//display message
  147 	G_Printf("XPSave: wrote %d xpsave records
", i);
  148 }
  149 
  150 //load client xpsave record
  151 qboolean G_XPSave_Load(gentity_t* ent) {
  152 	//declare variables
  153 	time_t		t;
  154 	char		userinfo[MAX_INFO_STRING], *guid;
  155 	int			clientNum, i, age;
  156 	qboolean	found						= qfalse;
  157 	g_XPSave_t	*x							= g_XPSaves[0];
  158 	char		agestr[MAX_STRING_CHARS];
  159 
  160 	//make sure this is a client
  161 	if(!ent || !ent->client) {
  162 		return qfalse;
  163 	}
  164 
  165 	//make sure xpsave is enabled
  166 	if(!(g_xpsave.integer & XPSAVE_ENABLED)) {
  167 		return qfalse;
  168 	}
  169 
  170 	//make sure we can get a valid time
  171 	if(!time(&t)) {
  172 		return qfalse;
  173 	}
  174 
  175 	//get client guid
  176 	clientNum = ent - g_entities;
  177 	trap_GetUserinfo(clientNum, userinfo, sizeof(userinfo));
  178 	guid = Info_ValueForKey(userinfo, "cl_guid");
  179 
  180 	//make sure client has a valid guid
  181 	if(!guid[0] || strlen(guid) != 32) {
  182 		return qfalse;
  183 	}
  184 
  185 	//determine if the client has an xpsave record
  186 	for(i=0; g_XPSaves[i]; i++) {
  187 		if(!Q_stricmp(g_XPSaves[i]->guid, guid)) {
  188 			found = qtrue;
  189 			x = g_XPSaves[i];
  190 			break;
  191 		}
  192 	}
  193 	if(!found) {
  194 		return qfalse;
  195 	}
  196 
  197 	//determine if xpsave record is expired
  198 	age = t - x->time;
  199 	if(age > g_xpsave_duration.integer) {
  200 		return qfalse;
  201 	}
  202 
  203 	//give client his xp
  204 	for(i=0; i<SK_NUM_SKILLS; i++) {
  205 		ent->client->sess.skillpoints[i] = x->skill[i];
  206 		ent->client->sess.startxptotal += x->skill[i];
  207 	}
  208 	ent->client->ps.stats[STAT_XP] = (int)ent->client->sess.startxptotal;
  209 
  210 	//recalculate client rank
  211 	G_CalcRank(ent->client);
  212 	BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qtrue);
  213 
  214 	//display message to client
  215 	G_XPSave_Duration(age, agestr, sizeof(agestr));
  216 	CP(va("print \"^3XPSave: loaded stored xpsave state from %s ago
\"", agestr));
  217 
  218 	//return success
  219 	return qtrue;
  220 }
  221 
  222 //store client xpsave record
  223 qboolean G_XPSave_Store(gentity_t* ent) {
  224 	//declare variables
  225 	time_t		t;
  226 	char		userinfo[MAX_INFO_STRING], *guid;
  227 	int			clientNum, i, j;
  228 	g_XPSave_t	*x									= g_XPSaves[0];
  229 	qboolean	found								= qfalse;
  230 
  231 	//make sure this is a client
  232 	if(!ent || !ent->client) {
  233 		return qfalse;
  234 	}
  235 
  236 	//make sure xpsave is enabled
  237 	if(!(g_xpsave.integer & XPSAVE_ENABLED)) {
  238 		return qfalse;
  239 	}
  240 
  241 	//make sure we can get a valid time
  242 	if(!time(&t)) {
  243 		return qfalse;
  244 	}
  245 
  246 	//make sure client is still connected
  247 	if(ent->client->pers.connected != CON_CONNECTED) {
  248 		return qfalse;
  249 	}
  250 
  251 	//get client guid
  252 	clientNum = ent - g_entities;
  253 	trap_GetUserinfo(clientNum, userinfo, sizeof(userinfo));
  254 	guid = Info_ValueForKey(userinfo, "cl_guid");
  255 
  256 	//make sure client has a valid guid
  257 	if(!guid[0] || strlen(guid) != 32) {
  258 		return qfalse;
  259 	}
  260 
  261 	//determine if client allready has an xpsave record
  262 	for(i=0; g_XPSaves[i]; i++) {
  263 		if(!Q_stricmp(g_XPSaves[i]->guid, guid)) {
  264 			x = g_XPSaves[i];
  265 			found = qtrue;
  266 			break;
  267 		}
  268 	}
  269 
  270 	//create new xpsave record for client
  271 	if(!found) {
  272 		if(i == XPSAVE_MAX_RECORDS) {
  273 			G_Printf("XPSave: cannot save record, XPSAVE_MAX_RECORDS exceeded (%i)", XPSAVE_MAX_RECORDS);
  274 			return qfalse;
  275 		}
  276 		x = malloc(sizeof(g_XPSave_t));
  277 		x->guid[0] = '\0';
  278 		for(j=0; j<SK_NUM_SKILLS; j++) {
  279 			x->skill[j] = 0.0f;
  280 		}
  281 		x->time = 0;
  282 		g_XPSaves[i] = x;
  283 	}
  284 
  285 	//store xpsave record
  286 	Q_strncpyz(x->guid, guid, sizeof(x->guid));
  287 	x->time = t;
  288 	for(i=0; i<SK_NUM_SKILLS; i++) {
  289 		x->skill[i] = ent->client->sess.skillpoints[i];
  290 	}
  291 
  292 	//return success
  293 	return qtrue;
  294 }
  295 
  296 //cleanup xpsave data
  297 void G_XPSave_Cleanup() {
  298 	//declare variables
  299 	int i = 0;
  300 
  301 	//cleanup xpsave data
  302 	for(i=0; g_XPSaves[i]; i++) {
  303 		free(g_XPSaves[i]);
  304 		g_XPSaves[i] = NULL;
  305 	}
  306 }
  307 
  308 //get duration of time
  309 void G_XPSave_Duration(int secs, char *duration, int dursize) {
  310 	if(secs > 1576800000 || secs < 0) {
  311 		Q_strncpyz(duration, "PERMANENT", dursize);
  312 	} else if(secs > 63072000) {
  313 		Com_sprintf(duration, dursize, "%d years", (secs / 31536000));
  314 	} else if(secs > 31536000) {
  315 		Q_strncpyz(duration, "1 year", dursize);
  316 	} else if(secs > 5184000) {
  317 		Com_sprintf(duration, dursize, "%i months", (secs / 2592000));
  318 	} else if(secs > 2592000) {
  319 		Q_strncpyz(duration, "1 month", dursize);
  320 	} else if(secs > 172800) {
  321 		Com_sprintf(duration, dursize, "%i days", (secs / 86400));
  322 	} else if(secs > 86400) {
  323 		Q_strncpyz(duration, "1 day", dursize);
  324 	} else if(secs > 7200) {
  325 		Com_sprintf(duration, dursize, "%i hours", (secs / 3600));
  326 	} else if(secs > 3600) {
  327 		Q_strncpyz(duration, "1 hour", dursize);
  328 	} else if(secs > 120) {
  329 		Com_sprintf(duration, dursize, "%i mins", (secs / 60));
  330 	} else if(secs > 60) {
  331 		Q_strncpyz(duration, "1 minute", dursize);
  332 	} else {
  333 		Com_sprintf(duration, dursize, "%i secs", secs);
  334 	}
  335 }
  336 
  337 //read strings from config file
  338 void G_XPSave_ReadConfig_String(char **cnf, char *s, int size) {
  339 	char *t;
  340 
  341 	t = COM_ParseExt(cnf, qfalse);
  342 	if(!strcmp(t, "=")) {
  343 		t = COM_ParseExt(cnf, qfalse);
  344 	} else {
  345 		G_Printf("XPSave: readconfig error (missing = before %s on line %d)
", t, COM_GetCurrentParseLine());
  346 	}
  347 	s[0] = '\0';
  348 	while(t[0]) {
  349 		if((s[0] == '\0' && strlen(t) <= size) || (strlen(t)+strlen(s) < size)) {
  350 			Q_strcat(s, size, t);
  351 			Q_strcat(s, size, " ");
  352 		}
  353 		t = COM_ParseExt(cnf, qfalse);
  354 	}
  355 	// trim the trailing space
  356 	if(strlen(s) > 0 && s[strlen(s)-1] == ' ') {
  357 		s[strlen(s)-1] = '\0';
  358 	}
  359 }
  360 
  361 //read integers from config file
  362 void G_XPSave_ReadConfig_Int(char **cnf, int *v) {
  363 	char *t;
  364 
  365 	t = COM_ParseExt(cnf, qfalse);
  366 	if(!strcmp(t, "=")) {
  367 		t = COM_ParseExt(cnf, qfalse);
  368 	} else {
  369 		G_Printf("XPSave: readconfig error (missing = before %s on line %d)
", t, COM_GetCurrentParseLine());
  370 	}
  371 	*v = atoi(t);
  372 }
  373 
  374 //read floats from config file
  375 void G_XPSave_ReadConfig_Float(char **cnf, float *v) {
  376 	char *t;
  377 
  378 	t = COM_ParseExt(cnf, qfalse);
  379 	if(!strcmp(t, "=")) {
  380 		t = COM_ParseExt(cnf, qfalse);
  381 	} else {
  382 		G_Printf("XPSave: readconfig error (missing = before %s on line %d)
", t, COM_GetCurrentParseLine());
  383 	}
  384 	*v = atof(t);
  385 }
  386 
  387 //write strings to config file
  388 void G_XPSave_WriteConfig_String(char *s, fileHandle_t f) {
  389 	char buf[MAX_STRING_CHARS];
  390 
  391 	buf[0] = '\0';
  392 	if(s[0]) {
  393 		Q_strncpyz(buf, s, sizeof(buf));
  394 		trap_FS_Write(buf, strlen(buf), f);
  395 	}
  396 	trap_FS_Write("
", 1, f);
  397 }
  398 
  399 //write integers to config file
  400 void G_XPSave_WriteConfig_Int(int v, fileHandle_t f) {
  401 	char buf[32];
  402 
  403 	sprintf(buf, "%d", v);
  404 	if(buf[0]) trap_FS_Write(buf, strlen(buf), f);
  405 	trap_FS_Write("
", 1, f);
  406 }
  407 
  408 //write floats to config file
  409 void G_XPSave_WriteConfig_Float(float v, fileHandle_t f) {
  410 	char buf[32];
  411 
  412 	sprintf(buf, "%f", v);
  413 	if(buf[0]) trap_FS_Write(buf, strlen(buf), f);
  414 	trap_FS_Write("
", 1, f);
  415 }

EDIT:
If you can’t read it with the code blocks the way they are, here are links to the files on my svn (use a tab size of 3 to get proper alignment):
g_xpsave.h
g_xpsave.c


(Xterm1n8or) #6

Wow :shock:

Didn’t think it would involve so much. And i was so chuffed when i added the stop refresh button to the playonline menu, it was only 1 line. Well 2 actually as i put it next to the refresh button and moved the connect to ip button to the new one. Seemed to me to be a more logical place for it.

Anyway, i have made a start, and thankyou very much for sharing your code, but its gone midnight and i’m getting to the point where i’m just staring blankely at the sceen :expressionless:

Will crack on tomorrow. Many thanks :stuck_out_tongue:


(Elite) #7

Ya, you won’t need near that much code when it’s all done, I was just too lazy and copied the whole page :slight_smile:


(Berzerkr) #8

I know, not what you wanted but modify the shortcut for ET (or use more shortcuts).

For example, change the destination of the shortcut in this way:

"D:\Games\Wolfenstein - Enemy Territory\ET.exe" +set fs_game etpro +password SECRET +connect IP:PORT

(Xterm1n8or) #9

Hi :smiley:

modify the shortcut for ET(or use more shortcuts)

That’s an idea. I could rename the shortcuts so i know which server i’m connecting to. But i really want to learn how to program this ingame. Thanks though :slight_smile:

Elite. Well i tried to go through the code and have read a few c++ tuts in how to open and read files :banghead: Need to take baby steps i think!
I think to start i would just like to be able to open and display the file with the manually typed ip addresses in.
This is what i’ve got so far, and it’s not much :frowning: :

//////////////////////////////////////////////////////////// g_ipsave.h ///////////////////////////////////////////////////////////

#ifndef G_IPSAVE_H
#define G_IPSAVE_H

// defines
#define IPSAVE_FILENAME		"ipsave.dat"			//name of ipsave file

//function prototypes
void G_IPSave_ReadConfig();					        //read ipsave records from file

#endif


//////////////////////////////////////////////////////////// g_ipsave.c ///////////////////////////////////////////////////////////

//includes
#include "g_local.h"

//declare variables

//read ipsave records from file
void G_IPSave_ReadConfig()
{
	int		len;
	fileHandle_t	f;
	char		*cnf;

	//open ipsave file
	len = trap_FS_FOpenFile(XPSAVE_FILENAME, &f, FS_READ) ;
	if(len < 0)
	{
		G_Printf("IPSave: Could not open file (%s)
", IPSAVE_FILENAME);
		return;
	}

	//read file
	cnf = malloc(len+1);
	trap_FS_Read(cnf, len, f);
	*(cnf + len) = '\0';

	//close file
	trap_FS_FCloseFile(f);

And this is what i added to the menu:

	itemDef {
		name		"efleftbackServer IP:"
		group		GROUP_NAME
		rect		$evalfloat((SUBWINDOW_X+4)+62+6) $evalfloat(SUBWINDOW_Y+32) $evalfloat((SUBWINDOW_WIDTH)-8-62-6) $evalfloat(50)
		style		WINDOW_STYLE_FILLED
		backcolor	.5 .5 .5 .2
		visible		1
		decoration
	}
	EDITFIELDLEFT( SUBWINDOW_X+4, SUBWINDOW_Y+32, (SUBWINDOW_WIDTH)-8, 50, "  IP List:", .2, 8, "ui_connectToIPAddress", 32, 25, "Saved IP addresses" )


	BUTTON( SUBWINDOW_X+6, SUBWINDOW_Y+SUBWINDOW_HEIGHT-64, .25*(SUBWINDOW_WIDTH-18), 14, "ADD", .24, 11, close playonline_connecttoip ; open playonline )
	BUTTON( SUBWINDOW_X+6, SUBWINDOW_Y+SUBWINDOW_HEIGHT-44, .25*(SUBWINDOW_WIDTH-18), 14, "REMOVE", .24, 11, close playonline_connecttoip ; open playonline )

Unfortunately i can’t show a pic at the moment. I’m hoping that getting this bit right, things will seem a bit clearer and i might have a hope in working out the rest. Any help appreciated. Many thanks :smiley:


(murka) #10

use xfire, it cant get any simpler than that


(Elite) #11

If you open up the ui/menumacros.h file (should be in the etmain folder in the sdk, not in the src folder) you will see all the different types of menu and interface controls available to use (I assume you are aware of this file allready).

If you look close, you will see thinsg like this:
WINDOW_STYLE_SHADER

This window style allows a shader (or image in other terms to be simple about it) to be placed in the backround. Now, if you make a small box with just you’re shader, it will be like an icon. Here is an example of what I mean, taken directly from the source (this is how the images for the playonline menu are done for example, more specifically this is the ‘filter password’ icon):

itemDef {
      name		"filtericonEmptyFull"
      rect		10 92 10 10
      style		WINDOW_STYLE_SHADER
      background	"ui/assets/filter_emptyfull"
      forecolor	1 1 1 1
      visible		1
      decoration
}

So, basically, in the above example, it just makes a small box to contain the shader (later on in the menumacros.h file it will call a script to change the icon, see the playonline.menu file to get more examples of this, or perhaps the credits menu’s also, thye have images too)

Once that is all done, you need to create a new shader, and place it in w/e file you like, as long as it is in the scripts folder, and the file ends with .shader. If you need help with these, let me know and I’ll throw down an example.


(Darkfrost) #12

You know, comments like these don’t actually help :lol:


(Ryan) #13

Your comment doesnt help much either :wink:

Never the less, maybe you COULD look at xfire, and how that programs logs the ips of the servers…?

Maybe you can take a look at that code? If its possible to look at it


(Xterm1n8or) #14

Hi ppl :smiley:

Regarding XFIRE:
I appreciate the suggestion, but i’m a novice programmer and have no idea how to hack into other programs. Also i’m not so sure that the code would help me. I’ve been reading c++ tuts into opening, reading and writing of files and have found several different ways (which is confusing the hell out of me), and none of them seem to be in the way ET does it.
Thankyou anyway :slight_smile:

Hi Elite,
If i understand correctly, you’re suggesting that i use an image, displayed in a small window beneath the Server IP textfield? So i make an image of IP addresses, which i have written in a txt file on my desktop, like so :

xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxx

I will try doing this, as it will bring me closer than anything that i have already tried, but i don’t see see how i can build on this, by adding an Add/Remove button, unless i keep making new images each time. Also i don’t think that i will ever be able to select just part of the image. i.e. 1 IP address to connect to.
I might be wrong, but it seems to me that the code has already been written in some form. For example, the Server Browser displays IP addresses (albeit from the internet and not a file) which you can click to connect, and ET reads and writes to cfg files doesn’t it?

I’ve tried to isolate the bits of code i would need to acheive this, but no joy so far :frowning: With full time job and 3 kids i can only do this after 9pm, when it’s quiet enough to concentrate, which doesn’t give me much time. But i shall plod on though.

Many thanks :smiley:


(Elite) #15

I’m not sure though exactly what you mean here. I am just a bit confused. Can you please rephrase exactly where the trouble spot is so we are for sure on the same page, thanks. More or less the part that I get not too sure about is the clicking image part. Just what do you want to happen, I understand this is where you are having problems, I am not to sure what you want to happen with it exactly (decoration, some purpose, etc)?


(Nail) #16

from what I understand, he wants a drop down menu in browser to choose between servers he likes, like the favorites list is supposed to do.


(Xterm1n8or) #17

Hi all :smiley:

I’ve just got some web space so that i can actually show you what i’m trying to do. I’m hoping that the images will explain things better. Unfortunately, doing this site has destracted me from doing what i’m tring to do, so i shall continue with my research now.

Here is the link: http://www.freewebs.com/xterm1n8or/outpost.htm

At the moment i’ll be happy with just displaying the IP addresses from a file or something. With this ‘template’ i will try to add the buttons and the select option etc.

Hope this helps, many thanks :smiley:


(carnage) #18

so u really do want to create a favorites list but for IP addresses?

i know favorites has a bug but if you open in ETpro mode then i think the favorites list is fixed and works in pretty much the way you describe


(Elite) #19

I am still somewhat confused on the purpose of the image (unless it is decoration, in this case I don’t see a problem, just create a box like I said in the previous post, any size you like, anywhere you like, and place the image in it).

In the case that the only purpose of the image is decoration, you’re best bet is to forget about the images until the system is done. It isn’t important to the overall function of the system, and is really only an extra effect.

Where I would go now is to finish the read/write code for the ip system I mentioned in a previous post. All you need to do is look at the code I posted, get an idea of one way to read/write configuration files, and evolve it into what you need.

This post seems very repetitive I know, but I don’t see an additional problem yet, other than what you had originally, which was coding the read/write system for this. If I am mistaken, please let me know more details of why you are having a problem, with what, and anything you have tried to solve the problem.


(Xterm1n8or) #20

Hi :smiley:

Sorry for the confusion :?

The thing is i am trying to finish the read/write code for the ip system you mentioned. I’ve been going through the code you kindly posted, but found it was a little too much for me. So, i’m trying to go through it step by step, by starting off with opening a file, reading the file and have it display the info in a box.

Elite: I seem to have misunderstood your post about the filter icon thing. I thought you were suggesting that i could display the info via this method using an image. :oops:

Carnage: Thanks for the suggestion, however i’m trying to do this myself and learn how to do some coding, so using another mod kind of defeats the object.

Like i said, i’ve tried to go through the code, isolating bits that i need, but am having trouble with putting it together. I was hoping somebody could help me do this first bit, then i will have a base to work from and add the other features to it.

Hope this makes sense. Thankyou all :slight_smile: