PDA

View Full Version : Cruise bug help.


jobans
6th January 2012, 20:20
In my cruise I have a problem when there is more about 10 connections cop system starts to bug. For example cant find anyone in some distance. In my cruise its 250. What could be the reason for that and how to fix it?

tbofram
6th January 2012, 22:00
can you give us a idea of what cruise insim your using? because without knowing the base for your insim no one can really help

jobans
7th January 2012, 13:23
Its cruise insim.

Azzano62
8th January 2012, 02:10
what link did you download it from, what was it example: lsc insim, lc insim? give us a name and we may be able to help you

jobans
8th January 2012, 07:29
Its LC insim

MadCatX
8th January 2012, 13:57
Have you made any modifications to the LC Cruise mod or do you use the version PoVo leaked?

jobans
8th January 2012, 15:13
It is PoVo leaked cruise. I repaired the cop system but now im got that it starts to buf when there is more than 8 players. So that means that there are some problems with MCI packets but I dont know what exactly.

MadCatX
8th January 2012, 15:29
You are probably not receiving the MCI packets correctly. One MCI packet contains only up to 8 CompCar data structures, so if there are more than 8 cars, LFS needs to send more than one MCI packet to give you information about all of them. If your cop system doesn't consider this situation, it's very likely to break down when it happens.

jobans
8th January 2012, 15:34
Any idea how to fix that?

MadCatX
8th January 2012, 16:53
Without knowledge of the code you use to process MCI packets and control the cop system I can't be of much assistance, but it should be pretty obvious. Your application should store cars' position by PLID, so a Dictionary sounds like the collection to use in this case.

broken
13th January 2012, 09:40
A common Cruise app. mistake, is that people loop the MCI packets by their local Players list count. This is wrong. The MCI packet is telling you how many connections it has sent you info for.

Imagine you have a shop, and I'm the storage facility you're loading from. The people I've hired can carry 8 bottles of water at a time. So they start unloading, and each time they bring 8 bottles, you look at how many you've ordered, and start yelling at my employees, because they haven't delivered the full amount. What can they possibly do? They will just go, and bring another 8 bottles, while you are in the store, totally confused, because you can't calculate (in this case - your insim app. can't calculate, because you haven't taught it how).

So, how do you fix this? Each time my employee comes, you count the bottles he has delivered, and compare them to what you have ordered. Then note it down, and on the next 8, do the same. Don't be so greedy. If my employees carry more than 8 bottles, they might just trip, and block access to your store, due to many bottles of water flying to random directions (= if many MCI packets are sent, your server might just drop a few people out, that's why they are 8 at a time).

So, I have no idea if you got it, but I just wanted to try a different method of explaining this exact issue, because nobody seems to get it the first time (neither did I, so don't worry - it's totally normal).

Now, that you know, here's some code:

In the MCI thread, EVERYWHERE you loop MCI packets, replace:
for (int i = 0; i < Players.Count; i++) with
for (int i = 0; i < MCI.CountC; i++)

Players.Count is how many bottles you've ordered. MCI.CountC is how many you receive in this one time. By the way, please note that if you just do a find/replace on your whole project, you will receive at least 1 error, because GetPlyIdx (iirc) is using this same loop for (int i = 0; i < Players.Count; i++). And the GetPlyIdx function is something that happens inside your store, it has nothing to do with my storage facility, so it should be, indeed, left as is - for (int i = 0; i < Players.Count; i++).

Please tell me if you understand or not. :D

MadCatX
13th January 2012, 10:27
...
That is quite good explanation of how the MCI packets work, with one exception though:

(= if many MCI packets are sent, your server might just drop a few people out, that's why they are 8 at a time).

Should be more like "= if many MCI packet was too large, your server might just drop a few people out, that's why it contains only 8 CompCar structures at a time"
:)

An alternative approach might be

Dictionary<byte, Point3D> carsPosition;

...

for(int i = 0; i < MCI.CountC; i++) {
byte _plid = MCI.CompCar[i].PLID;
int x = MCI.CompCar[i].X;
int y = MCI.CompCar[i].Y;
int z = MCI.CompCar[i].Z;

carsPosition[_plid] = new Point3D(x, y, z);
}

jobans
13th January 2012, 18:58
So I tried what broken write to me. In my case I dont have a code line for (int i = 0; i < Players.Count; i++) only in GetPlyIdx. Then I found that instead of for (int i = 0; i < Players.Count; i++) I have for (byte i = 0; i < MCI.NumC; i++). I tried to replace them with for (int i = 0; i < MCI.CountC; i++) but I got errors in all places where I replaced them. Error what I get is down there. Any Idea how to fix that? And what does those NumC mean?

Error 20 'LFS_External.Packets.IS_MCI' does not contain a definition for 'CountC' and no extension method 'CountC' accepting a first argument of type 'LFS_External.Packets.IS_MCI' could be found (are you missing a using directive or an assembly reference?)

MadCatX
13th January 2012, 19:11
The code you have right now is probably correct, but it most likely doesn't take in account the situation where you need more than one MCI packet to get updates for all cars on track. Without the full source of that for cycle we can't pinpoint where the problem is. MCI.NumC contains the information of how many CompCar structures are in the currently processed MCI packet. Each CompCar structure holds info about one car on the track. You can get this from the insim.h

broken
13th January 2012, 19:42
That is quite good explanation of how the MCI packets work, with one exception though:

Should be more like "= if many MCI packet was too large, your server might just drop a few people out, that's why it contains only 8 CompCar structures at a time"
:)

An alternative approach might be

Dictionary<byte, Point3D> carsPosition;

...

for(int i = 0; i < MCI.CountC; i++) {
byte _plid = MCI.CompCar[i].PLID;
int x = MCI.CompCar[i].X;
int y = MCI.CompCar[i].Y;
int z = MCI.CompCar[i].Z;

carsPosition[_plid] = new Point3D(x, y, z);
}


Thanks, yeah, you are right about the fix. And yeah, it is possible, but the cruise app he has already does store the info, and it uses it all over the place too, so such a change is, practically, impossible. Unless you are ready to overhaul the whole source.

So I tried what broken write to me. In my case I dont have a code line for (int i = 0; i < Players.Count; i++) only in GetPlyIdx. Then I found that instead of for (int i = 0; i < Players.Count; i++) I have for (byte i = 0; i < MCI.NumC; i++). I tried to replace them with for (int i = 0; i < MCI.CountC; i++) but I got errors in all places where I replaced them. Error what I get is down there. Any Idea how to fix that? And what does those NumC mean?

Error 20 'LFS_External.Packets.IS_MCI' does not contain a definition for 'CountC' and no extension method 'CountC' accepting a first argument of type 'LFS_External.Packets.IS_MCI' could be found (are you missing a using directive or an assembly reference?)


Double-click on the error. If you don't want to share more code (which won't harm you really, I can guarantee), just copy the line it points you to, and paste it here. Then, please copy that function (is this the right word? I mean, it's a function in PHP, but is this what it's called generally in programming as well?) and the MCI thread code. Or, again, if you don't want to share code - ask for an alternative - I guess we will think of something.

jobans
13th January 2012, 19:56
In total I have 26 errors. Eror is showing this line for (int i = 0; i < MCI.CountC; i++). It shows error because its not defined but I dont know where I need to define it.

broken
13th January 2012, 20:00
Ah, then please post the source of the whole MCI thread/function/whateveritiscalled.

jobans
13th January 2012, 20:27
Well this is my CompCar code if that what you wanted.

// Detailed car information packet (max 8 per packet)
private void MCI_CarInformation(Packets.IS_MCI MCI)
{
try
{
//CompCar is the CompCar packet structure I added to clsPlayer
int idx = 0;

for (int i = 0; i < MCI.NumC; i++)
{

idx = GetConnIdx(MCI.Info[i].PLID); //They aren't structures so you cant serialize!
Players[idx].CompCar.AngVel = MCI.Info[i].AngVel;
Players[idx].CompCar.Direction = MCI.Info[i].Direction;
Players[idx].CompCar.Heading = MCI.Info[i].Heading;
Players[idx].CompCar.Info = MCI.Info[i].Info;
Players[idx].CompCar.Lap = MCI.Info[i].Lap;
Players[idx].CompCar.Node = MCI.Info[i].Node;
Players[idx].CompCar.PLID = MCI.Info[i].PLID;
Players[idx].CompCar.Position = MCI.Info[i].Position;
Players[idx].CompCar.Speed = MCI.Info[i].Speed;
Players[idx].CompCar.X = MCI.Info[i].X;
Players[idx].CompCar.Y = MCI.Info[i].Y;
Players[idx].CompCar.Z = MCI.Info[i].Z;
decimal SpeedMS = (decimal) (((MCI.Info[i].Speed / 32768f) * 100f) / 2);

decimal Speed = (decimal)((MCI.Info[i].Speed * (100f / 32768f)) * 3.6f);
decimal ConvSpeed = (decimal)(Speed * 25 / 1000);
Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[i].PLID)].UniqueID)].TotalDistance += Convert.ToInt32(SpeedMS);
Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[i].PLID)].UniqueID)].DistanceSincePit += Convert.ToInt32(SpeedMS);
Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[i].PLID)].UniqueID)].LicenseDistance += Convert.ToInt32(SpeedMS);
//Connections[idx].DistanceSincePit += Convert.ToInt32(SpeedMS1);
Connections[idx].TotalDistance += Convert.ToInt32(SpeedMS);
Players[GetPlyIdx(MCI.Info[i].PLID)].Payout += ConvSpeed;


}
for (int i = 0; i < MCI.NumC; i++) //We want everyone to update before checking them.
{
MCI_Update(MCI.Info[i].PLID);

}

broken
13th January 2012, 21:06
Well this is my CompCar code if that what you wanted.


Please put the code in CODE or PHP tags from now on, because quote tags can't be quoted. :)

So, I can spot one major problem at the moment.

// Detailed car information packet (max 8 per packet)
private void MCI_CarInformation(Packets.IS_MCI MCI)
{
try
{
//CompCar is the CompCar packet structure I added to clsPlayer
int idx = 0;

for (int i = 0; i < MCI.NumC; i++)
{
// Look at Comment 1 first!
// --------------------------------------------------------
// Comment 2:
// You GetConnectionIndex (GetConnIdx).
// While you really need to GetPlayerIndex (GetPlyIdx).
// On top of that, you give GetConnIdx a PLID (Player ID).
// If you really needed to use GetConnIdx, you are supposed to give it an UCID (Unique Connection ID) too.
// Final conclusion: The line below is terribly wrong.
// --------------------------------------------------------
// Solution
// Replace the line below with the following:
// idx = GetPlyIdx(MCI.Info[i].PLID);
// --------------------------------------------------------

idx = GetConnIdx(MCI.Info[i].PLID);

// --------------------------------------------------------
// Comment 1:
// So, you want a players index.
// In Players[idx] the idx variable should be an index of the Players list (obviously).
// But instead, look at what happens in Comment 2.
// --------------------------------------------------------

Players[idx].CompCar.AngVel = MCI.Info[i].AngVel;
Players[idx].CompCar.Direction = MCI.Info[i].Direction;
Players[idx].CompCar.Heading = MCI.Info[i].Heading;
Players[idx].CompCar.Info = MCI.Info[i].Info;
Players[idx].CompCar.Lap = MCI.Info[i].Lap;
Players[idx].CompCar.Node = MCI.Info[i].Node;
Players[idx].CompCar.PLID = MCI.Info[i].PLID;
Players[idx].CompCar.Position = MCI.Info[i].Position;
Players[idx].CompCar.Speed = MCI.Info[i].Speed;
Players[idx].CompCar.X = MCI.Info[i].X;
Players[idx].CompCar.Y = MCI.Info[i].Y;
Players[idx].CompCar.Z = MCI.Info[i].Z;
decimal SpeedMS = (decimal) (((MCI.Info[i].Speed / 32768f) * 100f) / 2);

decimal Speed = (decimal)((MCI.Info[i].Speed * (100f / 32768f)) * 3.6f);
decimal ConvSpeed = (decimal)(Speed * 25 / 1000);
Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[i].PLID)].UniqueID)].TotalDistance += Convert.ToInt32(SpeedMS);
Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[i].PLID)].UniqueID)].DistanceSincePit += Convert.ToInt32(SpeedMS);
Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[i].PLID)].UniqueID)].LicenseDistance += Convert.ToInt32(SpeedMS);
//Connections[idx].DistanceSincePit += Convert.ToInt32(SpeedMS1);
Connections[idx].TotalDistance += Convert.ToInt32(SpeedMS);
Players[GetPlyIdx(MCI.Info[i].PLID)].Payout += ConvSpeed;
}

for (int i = 0; i < MCI.NumC; i++) //We want everyone to update before checking them.
{
MCI_Update(MCI.Info[i].PLID);
}
}
}

Look at the comments in the code. It's a small, but vital change. It's probably not the only problem, but it is one that is serious! And I don't think it will even get detected in build-time.

DarkTimes
14th January 2012, 08:45
is this the right word? I mean, it's a function in PHP, but is this what it's called generally in programming as well?

It's called a method in C#. As a general rule a function inside a class is called a method, outside of one it's called a function. Functions may also be refereed to as routines. All these terms are pretty interchangeable really.

broken
14th January 2012, 13:45
it's called a method in c#. As a general rule a function inside a class is called a method, outside of one it's called a function. Functions may also be refereed to as routines. All these terms are pretty interchangeable really.

<3

jobans
30th January 2012, 18:18
Sorry for this late answer but I only now got time to test it. So I have a little progressive news. Good is that when I changed GetConnIdx to GetPlyIdx my cop system sometimes works. Before when there was more than 8 connections it didnt work at all, but now it sometimes works for some cops and they can catch only some chosen civilians. And another bug is that when there are atleast 2 cops On DUTY, ok I will tell it like this - COP1 is chasing MrX, he busts him but the system shows that COP2 is arrested him. Hope you got that :D. So what could be problem for that?

jobans
6th February 2012, 12:19
Still waiting for help. :(

pinobr
7th March 2012, 21:17
I have the same problem... I hope that somebody can help us. :)

I think that the "big point" is how to add the CompCar Packet struct to the clsPlayer structure.

broken
8th March 2012, 09:24
Sorry for this late answer but I only now got time to test it. So I have a little progressive news. Good is that when I changed GetConnIdx to GetPlyIdx my cop system sometimes works. Before when there was more than 8 connections it didnt work at all, but now it sometimes works for some cops and they can catch only some chosen civilians. And another bug is that when there are atleast 2 cops On DUTY, ok I will tell it like this - COP1 is chasing MrX, he busts him but the system shows that COP2 is arrested him. Hope you got that :D. So what could be problem for that?


Well, sorry, but I can't help you at this point. The cause could be many things, and in order to fix it, I must be fully aware of how your code works. But, you have to catch me in a very weird mood in order to make me do that.

So, I would suggest something more general - get a programmer that knows his way around in C#, and can help you. Make him a partner on the server or something. In a real world, you would pay him to do that, but it's understandable that this is most likely nearly impossible, since (I guess) you are paying for a server, which you do in your free time only anyway.

Also, as a marketing advice for your server, if you start posting fixes for this insim on the forum, you may find more people connecting to see if the fixes really do make it all better, or not. Which, obviously, will result in more people and the server will gain popularity.

Long story short - getting a programmer in the current scenario is the best thing you can do.
(funny thing about that last paragraph - I actually posted it before the marketing advice and had to move it here, because the short story once again turned into a long one)

pinobr
9th March 2012, 02:02
I think that my code is the same code of jobans, based on .NET (C#) - Open Source Cruise Server (http://www.lfsforum.net/showthread.php?t=43103) and with the solution for MCI from elmohellno (http://www.lfsforum.net/showthread.php?t=43933), so the code is:

//CompCar is the CompCar packet structure I added to clsPlayer
int idx = 0;
for (int i = 0; i < MCI.NumC; i++)
{
idx = GetPlyIdx(MCI.Info[i].PLID);
Players[idx].CompCar.AngVel = MCI.Info[i].AngVel; //They aren't structures so you cant serialize!
Players[idx].CompCar.Direction = MCI.Info[i].Direction;
Players[idx].CompCar.Heading = MCI.Info[i].Heading;
Players[idx].CompCar.Info = MCI.Info[i].Info;
Players[idx].CompCar.Lap = MCI.Info[i].Lap;
Players[idx].CompCar.Node = MCI.Info[i].Node;
Players[idx].CompCar.PLID = MCI.Info[i].PLID;
Players[idx].CompCar.Position = MCI.Info[i].Position;
Players[idx].CompCar.Speed = MCI.Info[i].Speed;
Players[idx].CompCar.X = MCI.Info[i].X;
Players[idx].CompCar.Y = MCI.Info[i].Y;
Players[idx].CompCar.Z = MCI.Info[i].Z;
}

The big problem is how to "add the CompCar Packet struct to the clsPlayer structure" like elmohellno said.
Without this change, the compiler returns: "'LFS_External_Client.clsPlayer' does not contain a definition for 'CompCar' and no extension method 'CompCar' accepting a first argument of type 'LFS_External_Client.clsPlayer' could be found (are you missing a using directive or an assembly reference?)"

This is my problem and I think that jobans' too.

Thanks for any help!