The online racing simulator
Searching in All forums
(473 results)
MaKaKaZo
S2 licensed
Quote from SecondSkin :Posted this on the autox forum, but didn't get any response. Thought I'd try it here:

Is there any way to add minimum speed to autocross checkpoints (on any track), like is done in the LFS training modules? In the braking module, for instance, you can complete the course but you get a warning that your speed was too low and your time doesn't count. Is there any way to do this with a standard autox layout?

I guess this can be done with an InSim application. I don't know how autox checkpoints work... are they like normal track sector checkpoints? If so there's the chance that when a player crosses an autox checkpoint an IS_SPX packet might be sent. If that's the case then you can request an IS_MCI in which you can check the speed at that checkpoint.

There's also the possibility to check the speed at all times requesting MCI packets every second or so. If SPX packets are sent at checkpoints like I say above, then you can even set different minimum speeds for each sector of the layout.
MaKaKaZo
S2 licensed
Quote from Dygear :Learn something new everyday Thanks for that . So I take it that if there was only one car on track, then you would get one MCI packet, with the info value of 192? And while this information will give the ammout of players in the MCI packet, it will not give you the overall players. (Correct?)


<?php 
if ($MCI[0]->ComCar[0]->Info CCI_FIRST CCI_LAST AND $MCI[0]->ComCar[0]->Position != 1) {
    
# There is only one player in the race, and that driver is not first!
    # EPIC ERROR: PACKET ERROR, InSim ERROR, OR PROGRAM ERROR!
}
?>


Well, it gives enough info to know when a sequence starts and ends I didn't know about that either.


Good news guys: I managed to solve the UDP problem. As I thought it was a newbie mistake and some nice guy at www.codeguru.com helped me out checking my code.

The problem was that I wasn't binding the UDP socket to my local port. I mean, I specified that I wanted to use udpport 60000 and the server was sending packets to that port, but I never told my socket to listen on THAT port. I only told it to listen for incoming packets from IP x.x.x.x and port yyyy (the server's insim port).

So, when I use connect on the UDP socket without binding it previously to any specific port, it prepares a random port assuming that I'm going to start the communication (which I'm not). So, if I want to listen on a specific port I have to bind the socket first to my IP and port 60000 (the one I selected), and then use "connect()". That way my socket is prepared to listen on the desired port and not a random one.

I know most of you don't give a damn, but maybe someone that reads this will find it useful in the future. I'll be posting some example on car coordinates via UDP probably next week.
MaKaKaZo
S2 licensed
I'm trying now in a whats looks to be a nice forum for coders. If I get to solve it I'll post what was failing so people can laugh at my *probably* stupid mistake
MaKaKaZo
S2 licensed
Just forget the racism stuff and play the game, stop the racism discussion now please.
MaKaKaZo
S2 licensed
Would a name like "destruction checkers" fit better? The colours are already chosen and I don't know other words for white and black that are not racist. It's game made up by some spanish guy and I'm sure that he wasn't thinking about "negro" having racist connotations in English. I wasn't either when I posted the thread. Actually I've tried to change people's mind to make blacks->reds because black cars are harder to spot in the distance, but people still prefer black because they're opposite colors ans it's like checkers.
MaKaKaZo
S2 licensed
Dudes it's Spanish and we are talking about CARS!!!

Blancos = coches blancos (white cars)
Negros = coches negros (black cars)

There's no need to look for controversy in every word and less when it's a foreign language.

Btw, I've been on the black team every time because I like the black car better and I'm a winning streak, undefeated yet so... NEGROS FTW!!!

In Spain there's a much higher chance that people wouldn't want to be in the "blancos" team because it's Real Madrid (soccer team) color and there're a lot of Barcelona supporters that don't stand "being white", rather than people not wanting to be in the "negros" team for racism issues.
Last edited by MaKaKaZo, .
Blacks VS Whites (destruction derby-like team battles)
MaKaKaZo
S2 licensed
Hi guys! We've playing this blacks vs whites game for a couple of days now and just wanted to share the idea with all the community as it's a hell of fun!

First of all, this is not about a new "crash everyone server" or anything like that. We're a bunch of racers that just finished the current league season and right now we are spending some time fooling around to break with the training/racing routine.

The game is played between two teams with like 4 to 8 players each: blacks and whites. Whites use white car/white nickname, and blacks use black car/red nickname (black nicknames are harder to read).


The server is set to:

- Cruise ON (wrong way is a must).
- Small track (around 1 minute per lap).
- A few laps (3 or 4).


The only rule is: the team that gets a car to complete all laps win a point. The only thing that matters is who wins the race. Everything is allowed: speeding on pits, skipping the starting lights... everything!

When a team wins they add it to their score at the end of their nicknames (just to keep track of the score). A score limit is set so the first team to reach that score wins.

The use of TS/ventrilo is strongly recommended but you can play without it if you master the basic strategies.

Basic strategies are learnt quickly after some rounds, like quickly going to pits and rejoining when the other team runners are about to start a new lap so you catch with them as you exit the pits and then you have a good attack chance at the first corner. There're tons of tricks.

We don't prepare team beforehand unless there are majority of people from one team and they have their own TS server. Usually people randomly connect and join the team with less drivers/less points to have teams as balanced as possible.

I attach a replay of today's last round. The race is pretty lame in the beginning as blacks start pretty bad. As you guess there's no driving skill needed to play this, most of the time you don't need/shouldn't follow a proper line. But most of all... you are really not going to give a damn about driving properly

The awesome highlight of that replay is the last lap, as whites have three guys on lap, aiming to finish and blacks have only one but far away in the back. The rest of the blacks perform an amazing defense crushing all three white cars in the last corner/straight and they manage to win.

Believe me, this game is a lot of fun. I'm not a cruiser or a drifter, I'm a good old hotlapper/racer, but every once in a while these kind of games are really fun.
Last edited by MaKaKaZo, .
MaKaKaZo
S2 licensed
Quote from Dygear :InSim.txt Patch Z
struct IS_MCI // Multi Car Info - if more than 8 in race then more than one of these is sent
{
byte Size; // [B]4 + [U]NumP[/U] * 28[/B]
byte Type; // ISP_MCI
byte ReqI; // 0 unless this is a reply to an TINY_MCI request
byte NumC; // number of valid CompCar structs in this packet

CompCar Info[8]; // car info for each player, 1 to 8 of these (NumC)
};

I am guessing that's an error, meant to say NumC. But, with the MCI packets by them selves there is no way to find the amount of players in the race just by using the MCI packet. The only information it will give is the number of CompCar structs in the packet. So you will not know if you still have more coming. (Unless the number is less then eight of course, then that's the last packet, for the sequence.)

That's an interesting point. I haven't checked, but if it's really NumP as in all the players, then you don't know the size of that packet if there are more than 8 players. If it's to mean NumC then there's the possibility that the number of players is a multiple of 8 and you won't know which packet is the last of the sequence.

Anyway, you can always track the number of players connected at any given time so you wouldn't have problems. But that's right, you'd have to use more logic than just the info provided in the MCI packets.

Subliminal PS: Someone help me with the UDP stuff XDDD
MaKaKaZo
S2 licensed
Quote from the_angry_angel :UDP is sent a packet at a time, so unlike TCP (which is a stream) you don't have to worry about having partial packets, and having to have a global buffer, etc.

Totally right, hadn't thought about that. BUT, now that I think about it... if there's more than 8 people driving then multiple IS_MCI packets are sent "at the same time". That would cause problems, wouldn't it?
Last edited by MaKaKaZo, .
MaKaKaZo
S2 licensed
After some more testing, sniffing and stuff I've checked that the UDP packets are actually being sent, at least when I connect to a remote server.

My problem right now looks evident: the "select()" call for the UDP socket is not working. It times out and does not receive anything at all as it should (as I've checked that the info is being sent).


If I use only ony socket everything goes fine, but when I set up a second socket (in this case for the UDP packets) it won't receive anything.

I'm using two independent select() calls, one for each socket, and I don't know if that may be causing all the trouble. I'll post some code now.


This is the class delcaration:

#define PACKET_BUFFER_SIZE 512
#define PACKET_MAX_SIZE 512
#define IS_TIMEOUT 5

// Definition for our buffer datatype
struct buffer
{
char buffer[PACKET_BUFFER_SIZE]; // Packet buffer - 512 should be more than enough
unsigned int bytes; // Number of bytes currently in buffer
};

/**
* CInsim class to manage the Insim connection and processing of the packets
*/
class CInsim
{
private:
SOCKET sock; // TCP Socket (most packets)
SOCKET sockudp; // UDP Socket (if requested, for NLP and MCI)
byte using_udp; // 1 if we are using UDP for NLP or MCI packets
struct buffer gbuf; // Our global buffer
struct buffer lbuf; // Our local buffer
char packet[PACKET_MAX_SIZE]; // A buffer where the current packet is stored
fd_set readfd, exceptfd; // File descriptor watches
struct timeval select_timeout; // timeval struct for the select() call
struct buffer udp_gbuf; // (for NLP and MCI packets via UDP) Our global buffer
struct buffer udp_lbuf; // (for NLP and MCI packets via UDP) Our local buffer
char udp_packet[PACKET_MAX_SIZE]; // (for NLP and MCI packets via UDP) A buffer where the current packet is stored
fd_set udp_readfd, udp_exceptfd; // (for NLP and MCI packets via UDP) File descriptor watches
struct timeval udp_select_timeout; // (for NLP and MCI packets via UDP) timeval struct for the select() call
ofstream logfile;

public:
CInsim::CInsim(); // Constructor
// "int init(...)" Establishes connection with the socket and insim.
//+ The last argument ch_ver is a pointer to a IS_VER struct. If it's used an IS_VER packet
//+ will be returned. If ch_ver is not used in the call no IS_VER will be requested/returned.
int init (char *addr, word port, char *product, char *admin, struct IS_VER *pack_ver = NULL, byte prefix = 0, word flags = 0, word interval = 0, word udpport = 0);
int isclose(); // Closes connection from insim and from the socket
int next_packet(); // Gets next packet ready into "char packet[]"
char peek_packet(); // Returns the type of the current packet
void* get_packet(); // Returns a pointer to the current packet. Must be casted
int send_packet(void* packet); // Sends a packet to the host
int udp_next_packet(); // (UDP) Gets next packet ready into "char udp_packet[]"
char udp_peek_packet(); // (UDP) Returns the type of the current packet
void* udp_get_packet(); // (UDP) Returns a pointer to the current packet. Must be casted
int udp_send_packet(void* packet); // (UDP) Sends a packet to the host
};

This is the code used for establishing/connecting the two sockets and the connection to InSim:
(any var used not defined here is because it's a private member)

/**
* Initialize the socket and the Insim connection
* If "struct IS_VER *pack_ver" is set it will contain an IS_VER packet after returning. It's an optional argument
*/
int CInsim::init (char *addr, word port, char *product, char *admin, struct IS_VER *pack_ver, byte prefix, word flags, word interval, word udpport)
{
// Initialise WinSock
// Only required on Windows
WSADATA wsadata;

if (WSAStartup(0x202, &wsadata) == SOCKET_ERROR)
{
WSACleanup();
return -1;
}

// Create the TCP socket - this defines the type of socket
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// Could we get the socket handle? If not the OS might be too busy or have run out of available socket descriptors
if (sock == INVALID_SOCKET)
{
closesocket(sock);
WSACleanup();
return -1;
}

// Resolve the IP address
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));

saddr.sin_family = AF_INET;

struct hostent *hp;
hp = gethostbyname(addr);

if (hp != NULL)
saddr.sin_addr.s_addr = *((unsigned long*)hp->h_addr);
else
saddr.sin_addr.s_addr = inet_addr(addr);

// Set the port number in the socket structure - we convert it from host byte order, to network
saddr.sin_port = htons(port);

// Now the socket address structure is full, lets try to connect
if (connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
{
closesocket(sock);
WSACleanup();
return -1;
}

// If the user asked for NLP or MCI packets and defined an udpport
if ((udpport) && (flags >= ISF_NLP))
{
// Create the UDP socket - this defines the type of socket
sockudp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

// Could we get the socket handle? If not the OS might be too busy or have run out of available socket descriptors
if (sockudp == INVALID_SOCKET)
{
closesocket(sock);
closesocket(sockudp);
WSACleanup();
return -1;
}

// Resolve the IP address
struct sockaddr_in udp_saddr;
memset(&udp_saddr, 0, sizeof(udp_saddr));

udp_saddr.sin_family = AF_INET;

struct hostent *udp_hp;
udp_hp = gethostbyname(addr);

if (udp_hp != NULL)
udp_saddr.sin_addr.s_addr = *((unsigned long*)udp_hp->h_addr);
else
udp_saddr.sin_addr.s_addr = inet_addr(addr);

// Set the UDP port number in the UDP socket structure - we convert it from host byte order, to network
udp_saddr.sin_port = htons(port);

// Connect the UDP using the same address as in the TCP socket
if (connect(sockudp, (struct sockaddr *) &udp_saddr, sizeof(udp_saddr)) < 0)
{
closesocket(sock);
closesocket(sockudp);
WSACleanup();
return -1;
}

// We are using UDP!
using_udp = 1;
}

// Ok, so we're connected. First we need to let LFS know we're here by sending the IS_ISI packet
struct IS_ISI isi_p;
memset(&isi_p, 0, sizeof(struct IS_ISI));
isi_p.Size = sizeof(struct IS_ISI);
isi_p.Type = ISP_ISI;

if (pack_ver != NULL) // We request an ISP_VER if the caller asks for it
isi_p.ReqI = 1;

isi_p.Prefix = prefix;
isi_p.UDPPort = udpport;
isi_p.Flags = flags;
isi_p.Interval = interval;
memcpy(isi_p.IName, product, sizeof(isi_p.IName)-1);
memcpy(isi_p.Admin, admin, 16);

// Send the initialization packet
if(send_packet(&isi_p) < 0)
{
if (using_udp)
closesocket(sockudp);

closesocket(sock);
WSACleanup();
return -1;
}

// If an IS_VER packet was requested
if (pack_ver != NULL)
{
if (next_packet() < 0) // Get next packet, supposed to be an IS_VER
{
if (isclose() < 0)
{
if (using_udp)
closesocket(sockudp);

closesocket(sock);
WSACleanup();
return -1;
}
return -1;
}

switch (peek_packet()) // Check if the packet returned was an IS_VER
{
case ISP_VER: // It was, get it!
memcpy(pack_ver, (struct IS_VER*)get_packet(), sizeof(struct IS_VER));
break;
default: // It wasn't, something went wrong. Quit
if (isclose() < 0)
{
if (using_udp)
closesocket(sockudp);

closesocket(sock);
WSACleanup();
}
return -1;
}
}

return 0;
}

Here's the code for retrieving TCP packets. This seems to work fine in all cases:

/**
* Get next packet ready
* This function also keeps the connection alive as long as you keep calling it
*/
int CInsim::next_packet()
{
unsigned char oldp_size, p_size;
bool alive = true;

while (alive) // Keep the connection alive!
{
alive = false;
oldp_size = (unsigned char)*lbuf.buffer;

if ((lbuf.bytes > 0) && (lbuf.bytes >= oldp_size)) // There's an old packet in the local buffer, skip it
{
// Copy the leftovers from local buffer to global buffer
memcpy(gbuf.buffer, lbuf.buffer+oldp_size, lbuf.bytes-oldp_size);
gbuf.bytes = lbuf.bytes - oldp_size;

// Copy from global buffer back to the beginning of local buffer
memset(lbuf.buffer, 0, PACKET_BUFFER_SIZE);
memcpy(lbuf.buffer, gbuf.buffer, gbuf.bytes);
lbuf.bytes = gbuf.bytes;
}

p_size = (unsigned char)*lbuf.buffer;

while ((lbuf.bytes < p_size) || (lbuf.bytes < 1)) // Read until we have a full packet
{
// Set the timeout period
select_timeout.tv_sec = IS_TIMEOUT;
select_timeout.tv_usec = 0;

// Clear them
FD_ZERO(&readfd);
FD_ZERO(&exceptfd);

// Set them to watch our socket for data to read and exceptions that maybe thrown
FD_SET(sock, &readfd);
FD_SET(sock, &exceptfd);

int rc = select(sock + 1, &readfd, NULL, &exceptfd, &select_timeout);

if (rc == 0) // Timeout
continue;

if (rc < 0) // An error occured
return -1;

if (FD_ISSET(sock, &readfd)) // We got data!
{
// Recieve any waiting bytes
int retval = recv(sock, lbuf.buffer + lbuf.bytes, PACKET_BUFFER_SIZE - lbuf.bytes, 0);

// Deal with the results
if (retval == 0) // Connection has been closed at the other end
return -2;

if (retval < 0) // An error ocurred
return -1;

p_size = *lbuf.buffer;
lbuf.bytes += retval;
}
else if (FD_ISSET(sock, &exceptfd)) // An exception occured - we want to quit
return -1;
}

memset(packet, 0, PACKET_MAX_SIZE);
memcpy(packet, lbuf.buffer, p_size);

logfile << "UDP, ISP_" << (int)peek_packet() << ", " << (float)clock()/CLOCKS_PER_SEC << ", recv" << endl;

if ((peek_packet() == ISP_TINY) && (*(packet+3) == TINY_NONE))
{
alive = true;

struct IS_TINY keepalive;
keepalive.Size = sizeof(struct IS_TINY);
keepalive.Type = ISP_TINY;
keepalive.ReqI = 0;
keepalive.SubT = TINY_NONE;

// Send it back
if (send_packet(&keepalive) < 0)
return -1;
}
}

return 0;
}

And here's the code for retrieving UDP packets. This is the function that is giving me problems:

/**
* Get next UDP packet ready
*/
int CInsim::udp_next_packet()
{
unsigned char oldp_size, p_size;

oldp_size = (unsigned char)*udp_lbuf.buffer;

if ((udp_lbuf.bytes > 0) && (udp_lbuf.bytes >= oldp_size)) // There's an old packet in the local buffer, skip it
{
// Copy the leftovers from local buffer to global buffer
memcpy(udp_gbuf.buffer, udp_lbuf.buffer+oldp_size, udp_lbuf.bytes-oldp_size);
udp_gbuf.bytes = udp_lbuf.bytes - oldp_size;

// Copy from global buffer back to the beginning of local buffer
memset(udp_lbuf.buffer, 0, PACKET_BUFFER_SIZE);
memcpy(udp_lbuf.buffer, udp_gbuf.buffer, udp_gbuf.bytes);
udp_lbuf.bytes = udp_gbuf.bytes;
}

p_size = (unsigned char)*udp_lbuf.buffer;

while ((udp_lbuf.bytes == 0) || (udp_lbuf.bytes < p_size)) // Read until we have a full packet
{
// Set the timeout period
udp_select_timeout.tv_sec = IS_TIMEOUT;
udp_select_timeout.tv_usec = 0;

// Clear them
FD_ZERO(&udp_readfd);
FD_ZERO(&udp_exceptfd);

// Set them to watch our socket for data to read and exceptions that maybe thrown
FD_SET(sockudp, &udp_readfd);
FD_SET(sockudp, &udp_exceptfd);

int rc = select(sockudp + 1, &udp_readfd, NULL, &udp_exceptfd, &udp_select_timeout);

if (rc == 0) // Timeout
continue;

if (rc < 0) // An error occured
return -1;

if (FD_ISSET(sockudp, &udp_readfd)) // We got data!
{
// Recieve any waiting bytes
int retval = recv(sockudp, udp_lbuf.buffer + udp_lbuf.bytes, PACKET_BUFFER_SIZE - udp_lbuf.bytes, 0);

// Deal with the results
if (retval < 0) // An error ocurred
{
return -1;
}

p_size = *udp_lbuf.buffer;
udp_lbuf.bytes += retval;
}
else if (FD_ISSET(sockudp, &udp_exceptfd)) // An exception occured - we want to quit
return -1;
}

memset(udp_packet, 0, PACKET_MAX_SIZE);
memcpy(udp_packet, udp_lbuf.buffer, p_size);

logfile << "UDP, ISP_" << (int)udp_peek_packet() << ", " << (float)clock()/CLOCKS_PER_SEC << ", recv" << endl;

return 0;
}

I'm not sure if I'm doing something wrong with the sockets. If anyone is willing to check the code to help me I can provide tha full example and library code, executables, dlls and whatever you might want to give it a try.
MaKaKaZo
S2 licensed
Now that I'm not getting any help I'm wondering if anyone is currently using this TCP+UDP feature in InSim4 or everyone is just using full TCP for main and NLP/MCI packets in their applications.

Based on all the tests I've done I've come to the conclussion that the problem is in the InSim interface/reference or the server code, but not in my code. Let aside grabbing the UDP packets, it just seems like the server won't send the packets at all.

So, is someone currently using TCP+UDP???
Weird shadow above car
MaKaKaZo
S2 licensed
I was watching the replay from my yesterday night race and from the top view realized the shadow was very weird.

This is in FE3, weather 2 (I think), and the car was the XFG. I'm uploading a video to youtube right now. It certainly looks bad. Guess it has something to do with the latest graphics updates that now use 'subparts' or something like that.

Youtube link: http://www.youtube.com/watch?v=7FUvIxd9hj0
Last edited by MaKaKaZo, .
MaKaKaZo
S2 licensed
Many people who play mostly in cruise servers have issues, but the one that don't tolerate cruisers/drifters are the ones that have real issues...

Stop thinking that the line of development is going to change because of a lot of cruisers/drifters asking for their needs to be fulfilled. The devs have very clear in their mind how they want the sim to be, and that's their main goal. After that they listen to what the community asks for, and if they like the idea they do it, otherwise they don't. But that's the order: first come the devs plans, then community requests.

If a bunch of cruisers ask for some changes to develop cruising the devs may like it, but you can be sure they'll be putting racing and hotlapping in the first place of their priority list.

So, don't worry about non-racers and just let them be, no hard feelings. In the end the sim will be what the devs want it to be, not what the majority of users want. It jut happens that the devs usually want the same things in the game as we do!
MaKaKaZo
S2 licensed
Quote from migf1 :I seriously doubt that any average talented driver cannot reach the 103% of a wr in a given combo despite practicing tons of hours on that combo, as you say.

The point is that not every LFS player is an "average talented driver", there are people who are just very slow! And they train a lot, trust me!
MaKaKaZo
S2 licensed
Quote from St4Lk3R :this sounds like some sort of homework. is it a piece of homework?

Totally!
MaKaKaZo
S2 licensed
Why is eveybody trying to figure out something that is so clear? Like giving metaphysical explanations and such about practice and stuff...

There are people that have been practising for tons of hours, know every car, every track, have watched other people's replays hundreds of times... and they're not even within the 103% benchmark. Why? Because they CAN'T do better. Those "anti-aliens" seem to be perfectly fine, no one asks "why are these people so slow if they practice so much and so hard?"

Well, aliens are the same. They're just people that are very good! No one can practice and get beyond their limit. Alien's limit is just further than most people. That's it.

All the fuss about aliens is generated but the word itself. When people start using the word "alien" the rest of the people start thinking about guys that are different to the rest. Well, I'm sorry to disappoint you but they as different from a guy who can do a 100.10% from their WR than you are compared to your teammate that always does 100.10% of your time (given you are an average racer).

Where's the line that tells who's an alien and who's a very fast driver? I'll tell you: there's no line.

Think of how many people there could be out there that may be faster than the aliens we know but they just don't play LFS. What would those be?
MaKaKaZo
S2 licensed
Quote from sun :oh yer... my mistake sorry! i was supposed to say, how do you make a button that when it is clicked it brings up a dilog box where you can enter your information

Dude that's another thing

From the InSim documentation (people should try reading this before asking these kinds of questions):

struct IS_BTN // BuTtoN - button header - followed by 0 to 240 characters
{
byte Size; // 12 + TEXT_SIZE (a multiple of 4)
byte Type; // ISP_BTN
byte ReqI; // non-zero (returned in IS_BTC and IS_BTT packets)
byte UCID; // connection to display the button (0 = local / 255 = all)

byte ClickID; // button ID (0 to 239)
byte Inst; // some extra flags - see below
byte BStyle; // button style flags - see below
[COLOR=Red][B]byte TypeIn; // max chars to type in - see below[/B][/COLOR]

byte L; // left : 0 - 200
byte T; // top : 0 - 200
byte W; // width : 0 - 200
byte H; // height : 0 - 200

char Text[TEXT_SIZE]; // 0 to 240 characters of text
};

// ClickID byte : this value is returned in IS_BTC and IS_BTT packets.

// Host buttons and local buttons are stored separately, so there is no chance of a conflict between
// a host control system and a local system (although the buttons could overlap on screen).

// Programmers of local InSim programs may wish to consider using a configurable button range and
// possibly screen position, in case their users will use more than one local InSim program at once.

[COLOR=Blue]// TypeIn byte : if set, the user can click this button to type in text.

// Lowest 7 bits are the maximum number of characters to type in (0 to 95)
// Highest bit (128) can be set to initialise dialog with the button's text

// On clicking the button, a text entry dialog will be opened, allowing the specified number of
// characters to be typed in. The caption on the text entry dialog is optionally customisable using
// Text in the IS_BTN packet. If the first character of IS_BTN's Text field is zero, LFS will read
// the caption up to the second zero. The visible button text then follows that second zero.

// Text : 0-65-66-0 would display button text "AB" and no caption

// Text : 0-65-66-67-0-68-69-70-71-0-0-0 would display button text "DEFG" and caption "ABC"[/COLOR]

And...

// If the TypeIn byte is set in IS_BTN the user can type text into the button
// In that case no IS_BTC is sent - an IS_BTT is sent when the user presses ENTER

struct IS_BTT // BuTton Type - sent back when user types into a text entry button
{
byte Size; // 104
byte Type; // ISP_BTT
byte ReqI; // ReqI as received in the IS_BTN
byte UCID; // connection that typed into the button (zero if local)

byte ClickID; // button identifier originally sent in IS_BTN
byte Inst; // used internally by InSim
byte TypeIn; // from original button specification
byte Sp3;

char Text[96]; // typed text, zero to TypeIn specified in IS_BTN
};

Last edited by MaKaKaZo, .
MaKaKaZo
S2 licensed
Well, then please tell me how can I see my ctra image ingame. An consider asking becky rose about it, though I think she doesn't share her code. Inside a button you can only have 240 bytes that will be represented by LFS as text. If there's some way to trick LFS into loading a external image using that text (like a URL or something) I don't know how to do it.

Anyway, I'd like to see an ingame image first.
MaKaKaZo
S2 licensed
I have an image in my ctra account but I have never seen it ingame. Are you sure of what you mean?

Anyway, if that can be done, some tweaking must have been done somewhere because that's not an standard insim buttons feature.
MaKaKaZo
S2 licensed
Quote from filur ::drink:

Indeed the best solution But that is based in nodes I think. I see no better way to know the race position anyway.
MaKaKaZo
S2 licensed
I don't understand what you're asking for. Right now you have the X,Y,Z coordinates for each car in every MCI packet. Is that what you want?

Anyway, what are you going to do with the physical coordinates of the car? Having the coordinates you can know where the cars are, but... how do you know which one is ahead? You can't know that!

That's why nodes are used. Nodes follow the outline of the track so you have info on how far into the lap each car is. Knowing the coordinates only gives you the position of the car, but you can't know which car is ahead relative to a certain lap.
MaKaKaZo
S2 licensed
Ok, here are some logs. I'll tell first the procedure I'm following:
  • Start the dedicated server.
  • Start the insim application (this starts the connection to insim).
  • Connect a player to the server.
  • Add the player to the grid and the race starts.
  • MCI packets should start arriving by now.
  • Vote race to end.
  • After voting is complete type "!exit" to quit the insim application.
  • Close the dedicated server.
I hace repeated this procedure using:


FULL TCP
(MCI packets requested every one second via TCP)

Application log:
TCP, ISP_ISI, 0.046, send <-- InSim Initialization (ReqI != 0)
TCP, ISP_VER, 0.093, recv <-- IS_VER requested within IS_ISI
TCP, ISP_TINY, 0.109, send <-- TINY_NCN, asking for all connections
TCP, ISP_TINY, 0.109, send <-- TINY_NPL, asking for all players in grid
TCP, ISP_NCN, 0.125, recv <-- Reply to previous TINY_NCN (host is connected)
TCP, ISP_MSO, 8.578, recv <-- Text ("new guest connecting")
TCP, ISP_MSO, 9.062, recv <-- Text ("makakazo connected")
TCP, ISP_NCN, 9.062, recv <-- New player connected
TCP, ISP_MTC, 9.062, send <-- Welcome message to new player
TCP, ISP_BTN, 9.062, send <-- Buttons for X, Y, Z coordinates (this is the purpose of this example application)
TCP, ISP_BTN, 9.062, send
TCP, ISP_BTN, 9.062, send
TCP, ISP_STA, 9.109, recv <-- Race state
TCP, ISP_STA, 13.25, recv
TCP, ISP_NPL, 13.625, recv <-- Player added to grid
TCP, ISP_REO, 14.765, recv <-- Race restarting
TCP, ISP_RST, 14.765, recv <-- Race restarting
TCP, ISP_STA, 14.781, recv <-- Race state
TCP, ISP_MCI, 15.984, recv <-- MCI packets every one second
TCP, ISP_MCI, 16.984, recv
TCP, ISP_MCI, 17.984, recv
TCP, ISP_MCI, 18.984, recv
TCP, ISP_MCI, 19.984, recv
TCP, ISP_MCI, 20.984, recv
TCP, ISP_VTN, 21.89, recv <-- Player votes to end race
TCP, ISP_MSO, 21.906, recv
TCP, ISP_SMALL, 21.906, recv
TCP, ISP_MCI, 21.984, recv
TCP, ISP_MCI, 22.984, recv
TCP, ISP_MCI, 23.968, recv
TCP, ISP_TINY, 24.875, recv
TCP, ISP_TINY, 24.89, recv
TCP, ISP_STA, 24.921, recv
TCP, ISP_TINY, 30.093, recv
TCP, ISP_TINY, 30.093, send <-- Probably keepalive packet
TCP, ISP_MSO, 34.234, recv
TCP, ISP_MST, 34.234, send <-- "!exit"

Dedicated server log:
LFS DEDICATED HOST : 0.5Z
?
?
?
?
?
?
?
?
?
?
?
?
load bans
load font
-----
create english file
initialisations
tables
load objects
start intro
Aston
end of initialisation
Track loaded
Handicaps :
InSim - TCP : X-Y-Z Pos
Host Auth : 10.0.0.8
Send Track : 10.0.0.8
Alive : 10.0.0.8
Connecting guest still alive
Send Track : 10.0.0.8
Connect : 10.0.0.8
Sent OK to new guest
Sent scrutineering packet
Told guests about new guest
A new guest is connecting
Sent guest list to new guest
Sent new user packet
[Q3] makakazo^L connected (makakazo^L)
[Q3] makakazo^L voted to END RACE
Exit : clean up
Exit : delete
[Q3] makakazo : ^L!exit
InSim guest closed : X-Y-Z Pos
shutting down
free objects
free languages
free humans
free font
free host list
kill graphics
save config
free mouse
EXIT

FULL UDP
(MCI packets requested every one second via UDP using the same port as the rest of the packets)

Application log:
UDP, ISP_ISI, 0.015, send
UDP, ISP_VER, 0.046, recv
UDP, ISP_TINY, 0.046, send
UDP, ISP_TINY, 0.046, send
UDP, ISP_NCN, 0.078, recv
UDP, ISP_MSO, 6.671, recv
UDP, ISP_MSO, 7.203, recv
UDP, ISP_NCN, 7.203, recv
UDP, ISP_MTC, 7.218, send
UDP, ISP_BTN, 7.218, send
UDP, ISP_BTN, 7.218, send
UDP, ISP_BTN, 7.218, send
UDP, ISP_STA, 7.265, recv
UDP, ISP_STA, 9.312, recv
UDP, ISP_NPL, 9.343, recv
UDP, ISP_REO, 11.375, recv
UDP, ISP_RST, 11.375, recv
UDP, ISP_STA, 11.375, recv
UDP, ISP_MCI, 12.578, recv
UDP, ISP_MCI, 13.578, recv
UDP, ISP_MCI, 14.593, recv
UDP, ISP_MCI, 15.593, recv
UDP, ISP_VTN, 15.75, recv
UDP, ISP_MSO, 15.75, recv
UDP, ISP_SMALL, 15.75, recv
UDP, ISP_MCI, 16.593, recv
UDP, ISP_MCI, 17.578, recv
UDP, ISP_MCI, 18.593, recv
UDP, ISP_TINY, 18.734, recv
UDP, ISP_TINY, 18.765, recv
UDP, ISP_STA, 18.781, recv
UDP, ISP_MSO, 22.718, recv
UDP, ISP_MST, 22.734, send

Dedicated server log:
LFS DEDICATED HOST : 0.5Z
?
?
?
?
?
?
?
?
?
?
?
?
load bans
load font
-----
create english file
initialisations
tables
load objects
start intro
Aston
end of initialisation
Track loaded
Handicaps :
InSim - UDP : X-Y-Z Pos
Host Auth : 10.0.0.8
Send Track : 10.0.0.8
Connect : 10.0.0.8
Sent OK to new guest
Sent scrutineering packet
Told guests about new guest
A new guest is connecting
Sent guest list to new guest
Sent new user packet
[Q3] makakazo^L connected (makakazo^L)
[Q3] makakazo^L voted to END RACE
Exit : clean up
Exit : delete
[Q3] makakazo : ^L!exit
host : ^L* Closing application (requested by admin) *
InSim : unknown packet (80 bytes) - X-Y-Z Pos
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim timeout : X-Y-Z Pos
shutting down
free objects
free languages
free humans
free font
free host list
kill graphics
save config
free mouse
EXIT

TCP+UDP
(Main connections uses TCP, but MCI packets are requested every one second via UDP using a specific port)

Application log:
TCP, ISP_ISI, 0.031, send
TCP, ISP_VER, 0.031, recv
TCP, ISP_TINY, 0.031, send
TCP, ISP_TINY, 0.031, send
TCP, ISP_NCN, 0.062, recv
TCP, ISP_MSO, 4.484, recv
TCP, ISP_MSO, 4.984, recv
TCP, ISP_NCN, 4.984, recv
TCP, ISP_MTC, 4.984, send
TCP, ISP_BTN, 4.984, send
TCP, ISP_BTN, 4.984, send
TCP, ISP_BTN, 4.984, send
TCP, ISP_STA, 5.046, recv
TCP, ISP_STA, 6.593, recv
TCP, ISP_NPL, 6.64, recv
TCP, ISP_REO, 9.171, recv <-- Race restarting
TCP, ISP_RST, 9.171, recv <-- Race restarting
TCP, ISP_STA, 9.187, recv <-- Race state
TCP, ISP_VTN, 14.953, recv <-- Player votes to end race
TCP, ISP_MSO, 14.968, recv
TCP, ISP_SMALL, 14.968, recv
TCP, ISP_TINY, 17.937, recv
TCP, ISP_TINY, 17.968, recv
TCP, ISP_STA, 18, recv
TCP, ISP_MSO, 21.125, recv
TCP, ISP_MST, 21.125, send

Dedicated server log:
LFS DEDICATED HOST : 0.5Z
?
?
?
?
?
?
?
?
?
?
?
?
load bans
load font
-----
create english file
initialisations
tables
load objects
start intro
Aston
end of initialisation
Track loaded
Handicaps :
InSim - TCP : X-Y-Z Pos (UDP port 60000)
Host Auth : 10.0.0.8
Send Track : 10.0.0.8
Connect : 10.0.0.8
Sent OK to new guest
Sent scrutineering packet
Told guests about new guest
A new guest is connecting
Sent guest list to new guest
Sent new user packet
[Q3] makakazo^L connected (makakazo^L)
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim - UDP : no slots available
[Q3] makakazo^L voted to END RACE
InSim - UDP : no slots available
InSim - UDP : no slots available
InSim - UDP : no slots available
Exit : clean up
Exit : delete
[Q3] makakazo : ^L!exit
InSim guest closed : X-Y-Z Pos
shutting down
free objects
free languages
free humans
free font
free host list
kill graphics
save config
free mouse
EXIT

As you can see, when I'm using full TCP or full UDP the MCI packets are sent.

When using UDP I get a final last message "InSim : unknown packet (80 bytes) - X-Y-Z Pos" that I'm not sure what is causing it. The rest of "InSim - UDP : no slots available" arrive when I have already closed the application, they last for a while until LFS decides that it's been too long not receiving any UDP pakcet and closes the UDP connection due to a timeout.

When using TCP+UDP the main packets all arrive, but when MCI should start arriving the server says that "InSim - UDP : no slots available". This message stops when the vote to end race finishes and the player goes back to the main race config screen. In this screen no MCI packets are sent so there's no problem. With this method it looks like the server tries to send the MCI packets but for some reason it can't and delivers that message "no slots available".

I really don't know what is going on!
MaKaKaZo
S2 licensed
Quote from hyntty :Yes I am asking for someone to do it for me. I thought that was the point of this forum section. Sorry if I was confusing.

About the other stuff, well I don't know because I have no clue whatsoever about insim programming (unless making some knightrider led-lights with assebly counts ) (sorry, unnecessary joke). Anyway, the thing to do would be to ask Sören Scharf (if that's the way to spell his name), which for me is difficult cause I wouldn't know what to ask.

Second of all, would it help/have anything to do with it, if I didn't run the program on my computer?

It's ok, I just found your first post confusing, didn't know if you wanted help or someone to do it.

It's possible to do what you want, but the best way would be to ask the author of TV Director to add the features you are asking for.

I don't have time to do someone else's projects anyway, but good luck with this
MaKaKaZo
S2 licensed
But are you asking for someone to do it for you or for someone to help you with "how you should do it"?

It can be done, but you need to know stuff like what button IDs does the LFS TV Director use and more stuff.
MaKaKaZo
S2 licensed
Quote from Bean0 :I hope this is not possible.

It's not. You can only know his LFS username.
FGED GREDG RDFGDR GSFDG